views:

46

answers:

2

Hi, I'm trying to flatten an array for my form.

def update
  @tour = Tour.find(params[:id])
  params[:tour][:hotel_ids][0] = params[:tour][:hotel_ids][0].split(',')
...

This results in:

"hotel_ids"=>[["1","2"]]

Naturally I want it to be

"hotel_ids"=>["1","2"]

My Form:

<%= text_field_tag 'tour[hotel_ids][]', nil %>

Hope anyone can help with this.

EDIT


I've gotten it to work, somehow. This might be a bad way to do it though:

I changed the text_field that get's the array from jquery to:

<%= text_field_tag 'tour[h_ids][]', nil %>

then in my controller I did:

params[:tour][:hotel_ids] = params[:tour][:h_ids][0].split(',')

And this works, I had to add h_ids to attr_accessor though. And it will probably be a big WTF for anyone reading the coder later... but is this acceptable?

+3  A: 

This is ruby!

params[:tour][:hotel_ids][0].flatten!

should do the trick!

ps: the '!' is important here, as it causes the 'flatten' to be saved to the calling object.

pps: for those ruby-related questions I strongly suggest experimenting with the irb or script/console. You can take your object and ask for

object.inspect
object.methods
object.class

This is really useful when debugging and discovering what ruby can do for you.

Rock
I've been experimenting a lot in irb before posting, but my issue is how to make it work in rails. Let's say params[:tour][:hotel_ids][0] == ["1","2","3"] then calling flatten on that won't do anything. What I really need to be calling flatten on is the hotel_ids parameter.Hope this clarifies.
Amund
params[:tour][:hotel_ids].flatten!does not work then? Dont forget the '!'What does params[:tour][:hotel_ids].class .inspect return? Or try a buffer:buf = params[:tour][:hotel_ids][0] # or without the [0]buf.flatten!And check if thats what you want.
Rock
wait. What is params[:tour][hotel_ids][0] exactly? Do you need to call split(',') to get an Array in the first place? Then maybe just append the .flatten (without the '!') to params[:tour][:hotel_ids][0] = params[:tour][:hotel_ids][0].split(',').
Rock
params[:tour][hotel_ids][0] is an array I get from jquery. the value is ["1,3"], but since rails require the objects to strings I use split to create ["1","3"].
Amund
and after the split you get this double array [["1","3"]]? Then the flatten should work on this. params[:tour][:hotel_ids][0] = params[:tour][:hotel_ids][0].split(',').flatten should give you ["1","3"] then.
Rock
After the split the result is [["1","3"]], unfortunately .flatten doesn't work. I think this has to do with the fact that params[:tour][:hotel_ids][0].split(',') == ["1","3"]
Amund
params[:tour][:hotel_ids][0].split(',') == ["1","3"], so the problem is not the conversion here. What are you doing with params[:tour][:hotel_ids][0] after the conversion, that might cause the array-in-array problem?
Rock
MBO made a point in his edit: params[:tour][:hotel_ids][0] is of course position 0 in the params[:tour][:hotel_ids] Array. If you work with params[:tour][:hotel_ids] after the conversion, it will return a double array.Give the solution from MBO a try (params[:tour][:hotel_ids] = params[:tour][:hotel_ids][0].split(','))
Rock
Actually I were wrong, after running inspect it turns out params[:tour][:hotel_ids][0].split(',') == [["1","3"]]But then I do: params[:tour][:hotel_ids][0] = params[:tour][:hotel_ids][0].split(',').flattenand .inspect on params[:tour][:hotel_ids][0] == ["1", "2"] so far so good. But I end up with "hotel_ids"=>[["1","2"]] and the error: undefined method `to_i' for ["1", "2"]:Array.
Amund
Do you really want position 0 from the params[:tour][:hotel_ids] Array to be an Array of its own? if params[:tour][:hotel_ids][0] == ["1", "2"] then params[:tour][:hotel_ids] == [["1","2"]]. Please give params[:tour][:hotel_ids] = params[:tour][:hotel_ids][0].split(',') a try.Or post the code that uses the params hash and complains about .to_i
Rock
A: 

Simply use <%= text_field_tag 'tour[hotel_ids]', nil %> here, and then split like you do in example.

What really happens in your example is that Rails get param(-s) tour[hotel_ids][] in request and it thinks: "ok, so params[:tour][:hotel_ids] is an array, so I'll just push every value with this name as next values to this array", and you get exactly this behavior, you have one element in params[:tour][:hotel_ids] array, which is your value ("1,2"). If you don't need (or don't want) to assign multiple values to same param then don't create array (don't add [] at the end of the name)

Edit:

You can also go easy way (if you only want answer to posted question, not solution to problem why you have now what you expect) and just change your line in controller to:

params[:tour][:hotel_ids] = params[:tour][:hotel_ids][0].split(',')

#split returns array and in your example you assigned this new array to first position of another array. That's why you had array-in-array.

MBO
That was my initial idea as well, but the result came out "hotel_ids"=>"1,2". I want the hotel_ids to be an array of multiple objects collected from params[:tour][:hotel_ids][]
Amund
@Amund If you want multiple objects then you need multiple `<input>`'s in your html (or input with `multiple=true`), otherwise you have to create that multiple objects by yourself, with split(",") for example
MBO
Should I also have a hidden field with <%= hidden_field_tag 'tour[hotel_ids]', nil %> ?I tried with just altering the controller but the result was: "hotel_ids"=>["1,3"] yet inspect on params[:tour][:hotel_ids] == ["1", "3"]When I tried with a hidden_field I got Status: 500 Internal Server Errorexpected Array (got String) for param `hotel_ids'
Amund