1

I need to pass an array in a params, possible? Values can be, for example, ["1","2","3","4","5"] and these are strings but needs to eb converted to integers later.

I use a react_component in between a rails form_for. The html is like this:

<input type="hidden" name="people_id" id="people_id" value={this.state.people} />

The people array looks like this:

enter image description here

How can I pass the array in the value of the hidden field? The server error I got was

Im trying to do something like this in a model:

ids = params[:people_id]

ids.map do |b|
  Foo.create!(people_id: b.to_i)
end

If I ids.split(",").map I get symbol to int error.

Edit:

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

Still not sure what the issue is as nothing works. Here is a minimal reproduction of my code:

This answer is my react component and that's how I add to the array. Still in the component, I have the hidden field:

<input type="hidden" name="[people_id][]" id="people_id" value={this.state.people} />

_form.html.erb:

<%= form_for resource, as: resource_name, url: registration_path(resource_name), :html => { :data => {:abide => ''}, :multipart => true } do |f| %>
 <!-- react component goes here -->
 <%= f.submit  "Go", class: "large button" %>
<% end %> 

The story is, guest can select few people during registration in one go. Those people will be notified when registration is complete. Think of it as "I am inviting these people to bid on my tender". Those numbers, in the array, are user_ids.

users/registrations_controller.rb

class Users::RegistrationsController < Devise::RegistrationsController
  # POST /resource
  def create
   super do |resource|
    ids = params[:people_id].pop # logs now as "people_id"=>["1,2"]
    resource.save!(ids.split(",").map |b| Foo.create!(people_id: b.to_i) end)
   end
  end
end

New error on line resource.save:

no implicit conversion of Symbol into Integer

Edit #2

If I only have, in the create method:

ids.split(",").map do |b|
 resource.save!(Foo.create!(people_id: b.to_i))
end

It works! Foo is created two times each with the correct people_id.

Because I am creating more objects: Bar, I do not know how to do that in:

 resource.save!(<the loop for Foo> && Bar.create!())

The flow must be:

  1. Device creates the User
  2. Foo is created with the loop
  3. Bar is created
  4. etc

It has to be done that way as an User object is created on the fly.

Community
  • 1
  • 1
Sylar
  • 8,631
  • 20
  • 72
  • 139

1 Answers1

0

In Rails you use parameter keys with brackets on the end to pass arrays.

However you should not concatenate the values as a comma seperated list but rather send each value as a seperate param:

GET /foo?people_ids[]=1&people_ids[]=2&people_ids[]=3

That way Rails will unpack the parameters into an array:

Parameters: {"people_ids"=>["1", "2", "3"]}

The same principle applies to POST except that the params are sent as formdata.

If you want a good example of how this works then look at the rails collection_check_boxes helper and the inputs it generates.

<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
<label for="post_author_ids_1">D. Heinemeier Hansson</label>
<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
<label for="post_author_ids_2">D. Thomas</label>
<input id="post_author_ids_3" name="post[author_ids][]" type="checkbox" value="3" />
<label for="post_author_ids_3">M. Clark</label>
<input name="post[author_ids][]" type="hidden" value="" />

Updated:

If you intend to implement you own array parameters by splitting a string you should not end the input with brackets:

<input type="hidden" name="[people_id][]" value="1,2,3">

{"people_id"=>["1,2,3"]} 

Notice how people_id is treated as an array and the input value is the first element.

While you could do params[:people_id].first.split(",") it makes more sense to use the correct key from the get go:

<input type="hidden" name="people_id" value="1,2,3">

Also you don't really want to wrap the "root" key in brackets. Thats used in rails to nest a param key in a hash eg. user[name].

max
  • 76,662
  • 13
  • 84
  • 137
  • I use react so the state is an array. I add to the array with `concat`. Ill show you that code later. – Sylar Mar 31 '16 at 15:56
  • You can use a single input and split the string `params[:something].split(",")` but this is the *rails way* of passing arrays. – max Mar 31 '16 at 16:02
  • I don't have much experience with react but you would need to change the binding so that it generates a input for each item in the array instead of updating the value of single input. – max Mar 31 '16 at 16:04
  • See my updated post. That is exactly what I am doing. – Sylar Apr 01 '16 at 06:20
  • Ok. Before trying out your updated answer, my loop works. The thing is a user is created with `resource.save` with actions: `resource.save!(Bar.create())`. I'm trying to add a loop in the `resource.save` and that's where the issue is. – Sylar Apr 01 '16 at 07:34
  • What you are doing is a pretty strange and convoluted way of doing what is usually done with the `ids=` setters (assigning records) or nested attributes. I would recommend you figure out how to do it in vanilla rails before trying to do it with react. – max Apr 01 '16 at 07:47