How to access nested params in controller

Hello,

I'm trying to check some value in the controller so that I can change the behavior accordingly. I have a form set up such that when submitted, the params looks like this:

{ "transport"=>{ "from_location"=>"Portland",

"transports_transits_attributes"=>{"1246482280809"=>{"city"=>"Osaka", "country"=>"2"}, "0"=>{"city"=>"Seattle", "country"=>"1"}},

"to_location"=>"Tokyo", "departure_date"=>"01-Jul-2009", "arrival_date"=>"02-Jul-2009"} }

My question is in regards to the nested table "transports_transits" that you see in the middle with two records. How would I access the specific values in the nested table? I know I can populate the model by @transport = Transport.new(params[:transport]), but what if I want to access one of the values in "transports_transits" table, say, to get value "Osaka"?

Thanks!

If I understand the question correctly you eant something like params[:transports_transits_attributes][:1246482280809][:city] I think.

Colin

Thanks, Colin. I tried what you suggested like this (with quotes around the number), and it worked.

params[:transport][:transports_transits_attributes][:"0"][:city] ==> gets me "Seattle" from the initial example.

The problem I have now is that the numbers ("0" and "1246482280809") are auto-assigned, so I don't know how I would access them then. The first one always seem to get "0", but there can be many more transports_transits for one transport, and all but the first will get a random number assigned. Is there a way I can access them without referring to these numbers? For example, I can get the length of the array like this:

len = params[:transport][:transports_transits_attributes].length

and I would love to be able to iterate through the array like this (sorry for the bad syntax, but you get the idea..):

for (int i=0; i<len; i++)   params[:transport][:transports_transits_attributes](i)[:city]

but I can't seem to do that. Any suggestions? Thanks! Kumi

It should be [i] not (i) but a much more railsy way is

params[:transport][:transports_transits_attributes].each do |attr|   # do something with attr[:city] end

However, I have to say that you seem to be doing rather unusual things which, when I find myself in such a situation, usually means I am tackling something in the wrong way. Can I ask why are you parsing the params in the first place rather than using them to build objects in the usual way?

Colin

That did cross my mind, but I also wanted to know how to do something like this if it was possible. attr[:city] didn't work..

But here's what I'm really trying to do. I have a form that lets user enter transport information like arrival/ departure airports, time, etc. If there are transits in between, user can add as many transits as they like - or None. When the form is submitted, even when there are no transits, there is one empty transports_transits_attributes, and I'm trying to catch that somehow so it doesn't get saved to the database with blanks.

Here's the model:

That did cross my mind, but I also wanted to know how to do something like this if it was possible. attr[:city] didn't work..

Use the debugger to find out why attr[:city] does not work. Google ruby-debug and look in the ruby guides and railscasts for how to use it if necessary.

But here's what I'm really trying to do. I have a form that lets user enter transport information like arrival/ departure airports, time, etc. If there are transits in between, user can add as many transits as they like - or None. When the form is submitted, even when there are no transits, there is one empty transports_transits_attributes, and I'm trying to catch that somehow so it doesn't get saved to the database with blanks.

Here's the model:

-------------------------------------------- class Transport < ActiveRecord::Base

has_many :users, :through => :transports_users has_many :transports_transits, :dependent => :destroy accepts_nested_attributes_for :transports_transits, :allow_destroy => true

end --------------------------------------------

and the form snippet for where transits are added/removed

-------------------------------------------- <div id="transits" style="display: none"> <% f.fields_for :transports_transits do |i| %> <%= render :partial => 'transport_transit', :locals => { :form => i } %> <% end %> </div> <%= add_transport_transit_link(f) %> --------------------------------------------

and in the helper, I have -------------------------------------------- def add_transport_transit_link(form_builder) link_to_function 'Add transits' do |page| form_builder.fields_for :transports_transits, TransportsTransit.new, :child_index => 'NEW_RECORD' do |f| html = render(:partial => 'transport_transit', :locals => { :form => f }) page << "if($('transits').visible()) $('transits').insert ({ bottom: '#{escape_javascript(html)}'.replace(/NEW_RECORD/g, new Date ().getTime()) }); else $('transits').show();" end end end --------------------------------------------

As you can see, at first, this div is invisible and only becomes visible when the add_transport_transit_link is clicked for the first time by the user. The subsequent click will actually add more transport_transit form.

*** So the real problem is that the first transit form is there (although invisible).***

I couldn't figure out how to not have the first transit initially - and that's why I was trying to deal with it after the fact. I hope I'm making sense here.

This is a bit out of my comfort zone, can anyone else help?

Colin

Thanks, Colin.

I don't understand why yet, but this seems to get the value in the nested table.

Please disregard my question above.. I figured out what I was doing wrong. In the controller (in "def new"), I had

@transport.transports_transits.build

which was the problem all along. This was the reason I had one record in the nested table even when there was no transit record entered by the user. I commented it out, deleted the " if visible" part in helper method, and made the nested transit form visible to start with and everything works fine now.

Colin, thanks anyway - I learned how to read the params somewhat and now I know about the ruby-debug gem! :slight_smile:

Kumi