32

Submitting a class roster. Adding 3 students at once. Each student has first, last, age.

Question: How can we get all of the students in an array of arrays?

students[0] => Array (
  ["first"] => "first name for 0",
  ["last"] => "last name for 0",
  ["age"] => "age for 0"
),
students[1] => Array (
  ["first"] => "first name for 1",
  ["last"] => "last name for 1",
  ["age"] => "age for 1"
), 
...  

Details
For one student:

<input type="text" name="first">  
<input type="text" name="last">  
<input type="text" name="age">  

We can return multiple students in separate arrays like this:

<input type="text" name="students[first][]">  
<input type="text" name="students[last][]">  
<input type="text" name="students[age][]">  

which returns an array of firsts, lasts and ages

students["first"] = [array of first names]
students["last"] = [array of last names]
students["age"] = [array of ages]  

Theoretically we can get all the info for a student by accessing the same index (say "3" for each array).

We do not want to programatically add an index in the form.
Do not want:

<input type="text" name="students[hardcoded_index][first]">  
<input type="text" name="students[hardcoded_index][last]">  
<input type="text" name="students[hardcoded_index][age]">  

If for any reason it matters, we are using Rails for views but can use form helpers or HTML.

2 Answers 2

46

tl;dr: Add empty brackets ([]) after students to the input names.

Fiddling with Rack::Utils.parse_nested_query it seems you can get the payload you want like this:

<!-- first student -->
<input type="text" name="students[][first]">
<input type="text" name="students[][last]">
<input type="text" name="students[][age]">

<!-- second student -->
<input type="text" name="students[][first]">
<input type="text" name="students[][last]">
<input type="text" name="students[][age]">

Note the empty brackets ([]) after students. This tells Rack you want the students param to be an array. Subsequent params encountered (with the same name) will start a new element.

POST /myroute?students[][first]=foo&students[][last]=bar&students[][age]=21&students[][first]=baz&students[][last]=qux&students[][age]=19

Gets parsed like this:

{"students" => [
  {
    "first" => "foo",
     "last" => "bar",
      "age" => "21"
  },
  {
    "first" => "baz",
     "last" => "qux",
      "age" => "19"
  }
]}

Further reading: http://codefol.io/posts/How-Does-Rack-Parse-Query-Params-With-parse-nested-query

Sign up to request clarification or add additional context in comments.

4 Comments

I don't know what Flask is, but probably not. This answer is specific to Ruby on Rails.
I am using Rails4. This approach made the HTTP POST request correctly with all the students info (as i confirmed from the chrome network inspector). But inside the controller.create method (using binding.pry), when i see params it shows an array of the students but contains ONLY one hash in it - only the last student's hash - the previous students are missing inside the params. What am i doing wrong here?
For those using Django & DRF, the format required is students[0]first (no dot, unique, specified indexes) as I finally found here: stackoverflow.com/a/57013811/3507333
For those using asp.net, this dynamic format doesn't work on asp.net controller binding. so any one from .net community. as of net 9 this isn't supported.
25

I know the question is old , but I would like to add my experiences also for future readers.

For those of you who want to process the data in a PHP enviroment , @messanjah's method won't work ,

The methods for parsing data like the built-in serializeArray or serialize are not parsing it as expected either.

This is what I tried so far ...

  • students[name]
  • students[][name] - Very Strange since it was meant to automatically index the array
  • students[name][]

Neither of them worked, but this students[<hardcoded-index>][name] worked for PHP ,

I know that although the question is against this method , but it will be useful for PHP users who will land here in the nearby future as the asker needed it for Ruby On Rails.

The method you choose to hard code the indexes is upto you , you can use a cleaner method by using javascript or you can manually hard code them initially in your form element.

Cheers

3 Comments

This is very interesting. Does this imply the difficulty surrounding this particular task is not a rails specific thing, but a HTML thing?
Exactly! - but I believe the problem is already solved by now or at least a workaround is available more prettier than this one :D
i hope so, it’s a little confusing for me, but still a great help. If you know I’d any newer techniques please share the link

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.