Merging POST values into one map

Hi,
I stumbled upon a problem when I tried to make dynamically generated forms.
I’m trying to list some elements, each has 2 properties - id and selected?.
I implemented those properties as hidden_inputs:

<%= hidden_input(@form, :hidden, name: "data[][id]", value: @data.id) %>
<%= hidden_input(@form, :hidden, name: "data[][selected?]", value: "false") %>

I expected POST request to be list of maps with 2 keys. Logs showed that I’m getting list of maps with one key:

%{"_csrf_token" => "FykPHTkdHA0JDE4pIiYtC1ViQAwMNgAAScbpO/YoY4vgLJcBz68BEg==",
"_utf8" => "✓",
 "data" => [
  %{"id" => "aH5aq4V0Ywk"},
  %{"selected?" => "false"}, 
  %{"id" => "d1vQMIisJuc"}, 
  %{"selected?" => "false"}, 
  %{"id" => "TtXMeMR81q4"}, 
  %{"selected?" => "false"},
  %{"id" => "Shk7qcvqDOo"}, 
  %{"selected?" => "false"}, 
  %{"id" => "YnGgGIlnlNI"},
  %{"selected?" => "false"}, 
  %{"id" => "CpaOh4poNms"}, 
  %{"selected?" => "false"}, 
  %{"id" => "A7lxd7RL1To"}, 
  %{"selected?" => "false"}
], 
"format" => "MP3"}

So I think [] in name just creates new entry.
How can I make maps like:

%{"id" => "YnGgGIlnlNI", "selected?" => "false"}, (...)

Putting [] at end gives me values as list of each input:

%{"_csrf_token" => "FCMOOh9TN00Fc3EYNy04CGEsCzcPAAAAPicWiar/UKIVYAvANxsyFQ==",
"_utf8" => "✓", 
"data" => %{
  "id" => ["aH5aq4V0Ywk", "d1vQMIisJuc", "TtXMeMR81q4", "Shk7qcvqDOo", "YnGgGIlnlNI", 
    "CpaOh4poNms", "A7lxd7RL1To"], 
  "selected?" => ["false", "false", "true", "false", "true", "false", "false"]
}, 
"format" => "MP3"}

If there’s no resolution I’m gonna stick with 2nd way, but maybe it can be done as I want to?

I’m not sure but I think you can use your @data.id to identify the fields

<%= hidden_input(@form, :hidden, name: "data[#{@data.id}][id]", value: @data.id) %>
<%= hidden_input(@form, :hidden, name: "data[#{@data.id}][selected?]", value: "false") %>

You inspired me to do something similar:

<%= hidden_input(@form, :hidden, name: "data[][#{@data.id}][selected?]", value: "false") %>

Which gives:

"data" => [
%{"aH5aq4V0Ywk" => %{"selected?" => "false"}},
%{"d1vQMIisJuc" => %{"selected?" => "false"}}, 
%{"TtXMeMR81q4" => %{"selected?" => "false"}}, 
%{"Shk7qcvqDOo" => %{"selected?" => "false"}}, 
%{"YnGgGIlnlNI" => %{"selected?" => "false"}}, 
%{"CpaOh4poNms" => %{"selected?" => "false"}}, 
%{"A7lxd7RL1To" => %{"selected?" => "false"}}]

Which is better, as I can pattern match this and I’m using only one field, but I wonder if I can take this further.

2 Likes

What does the request looks like if you do "data[#{@data.id}][id]"?

"data" => %{
  "A7lxd7RL1To" => %{"id" => "some_id"}, 
  "CpaOh4poNms" => %{"id" => "some_id"}, 
  "Shk7qcvqDOo" => %{"id" => "some_id"}, 
  "TtXMeMR81q4" => %{"id" => "some_id"}, 
  "YnGgGIlnlNI" => %{"id" => "some_id"}, 
  "aH5aq4V0Ywk" => %{"id" => "some_id"},
  "d1vQMIisJuc" => %{"id" => "some_id"}
}

With two fields:

"data" => %{
  "A7lxd7RL1To" => %{"id" => "", "selected?" => "false"}, 
  "CpaOh4poNms" => %{"id" => "", "selected?" => "false"},
  "Shk7qcvqDOo" => %{"id" => "", "selected?" => "false"},
  "TtXMeMR81q4" => %{"id" => "", "selected?" => "false"}, 
  "YnGgGIlnlNI" => %{"id" => "", "selected?" => "false"}, 
  "aH5aq4V0Ywk" => %{"id" => "", "selected?" => "false"}, 
  "d1vQMIisJuc" => %{"id" => "", "selected?" => "false"}
}

So that’s isn’t helping, as I get duplicated id field. I would have to discard id key in latter processing and then I’d get what I want.