jj008
jj008

Reputation: 1093

Passing array of objects as param to rails controller

I have an array of objects on my frontend that I want to pass to my rails controller.

The array of object I'm passing to my controller looks like this:

[ 
  {id: 1, position: 1}, 
  {id: 2, position: 2}
]

In my controller, I'm trying to do something like this:

def map
  params[:items].each do |item|
    todo = @user.todos.new(
      item_id: item.id,
      item_position: item.position
    )
    todo.save!
  end
end

I tried JSON.stringify on my array and then sending it to my controller but everything is a string so a lot of my methods are not working.

What is the correct way to pass in an array of objects to a rails controller?

Upvotes: 0

Views: 4019

Answers (1)

Thomas
Thomas

Reputation: 622

If params[:items] is a string ("[{:id=>1, :position=>1}, {:id=>2, :position=>2}]"), then you can use eval(). That will return an array.

Try in your rails console:

pry(main)> eval("[{:id=>1, :position=>1}, {:id=>2, :position=>2}]")
=> [{:id=>1, :position=>1}, {:id=>2, :position=>2}]

So, in your case this should do the trick:

def map
  arr = eval(params[:items])
  arr.each do |item|
    todo = @user.todos.new(
      item_id: item[:id]
    )
    todo.save!
  end
end

Hope it helps.

EDIT: It is perhaps 🤪NOT the most secure thing to do to call eval on a string that has been submitted from outside (see my "mea culpa" comment below").

So I played around with this problem and the only way I can come up with would be to encode the array in the front end and decode it in your controller. It can still rais an error if the value is NOT an array of hashes so you should have an error handler in your controller...

in JS:

let array = [{id: 1, position: 1}, {id: 2, position: 2}]
let yourParamToSendOff = escape(JSON.stringify(array))

And on your back-end:

JSON.parse(CGI.unescape("%5B%7B%22id%22%3A1%2C%22position%22%3A1%7D%2C%7B%22id%22%3A2%2C%22position%22%3A2%7D%5D"))
=> [{"id"=>1, "position"=>1}, {"id"=>2, "position"=>2}]

Sorry about my first answer....

Upvotes: 1

Related Questions