Forum: Ruby on Rails Params error with: complex form+multiple models

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
David S. (Guest)
on 2008-12-09 18:05
Hello,

I'm trying to create a complex form with multiple models.

The problem is that the params hash is sent out of order to the
controller, and the data is saved wrong in the database.

What I get is:
 Parameters: {"commit"=>"Cadastrar", "invoice"=>{"mode"=>"in",
"total"=>"34", "items_attributes"=>[{"item"=>"3333333"},
{"quantity"=>"3333333", "item"=>"666666"}, {"price"=>"3333333",
"quantity"=>"666666"}, {"price"=>"4666666"}], "company_id"=>"10"},....

But what I want is:
 Parameters: {"commit"=>"Cadastrar", "invoice"=>{"mode"=>"in",
"total"=>"34", "items_attributes"=>[{"item"=>"3333333",
"quantity"=>"3333333", price"=>"3333333"},{"item"=>"666666",
"quantity"=>"666666","price"=>"666666"}], "company_id"=>"10"},...


Codes are:

Controller: http://pastie.org/334963
Models: http://pastie.org/334965
Views: http://pastie.org/334967

Does anyone know my error?
Any help will be thankfull.

David S.
David S. (Guest)
on 2008-12-10 23:56
up,

anyone?
David S. (Guest)
on 2008-12-13 17:22
Does any one know how to fix? Or any suggestion will be ok.
I did not find the solution yet.

David S.
Frederick C. (Guest)
on 2008-12-13 17:53
(Received via mailing list)
On Dec 13, 3:22 pm, David S. <removed_email_address@domain.invalid>
wrote:
> Does any one know how to fix? Or any suggestion will be ok.
> I did not find the solution yet.
>
Given that it's an ajax form (ie serialized by prototype), it's worth
checking that you form elements have unique dom ids as that sort of
stuff will confuse prototype.

Fred
David S. (Guest)
on 2008-12-15 03:14
Hi Fred,
thanks for answered.

So, I have this code generated:

<div id="invoice_items">
<div class="invoice_item">
<label for="invoice_items_attributes__item">item</label>
<input id="invoice_items_attributes__item" type="text" size="30"
name="invoice[items_attributes][][item]"/>
<label for="invoice_items_attributes__quantity">quantity</label>
<input id="invoice_items_attributes__quantity" type="text" size="30"
name="invoice[items_attributes][][quantity]"/>
<label for="invoice_items_attributes__price">Price</label>
<input id="invoice_items_attributes__price" type="text" size="30"
name="invoice[items_attributes][][price]"/>
<a onclick="this.up('.invoice_item').remove(); return false;"
href="#">remover</a>
</div>
<div class="invoice_item">
<label for="invoice_items_attributes__item">item</label>
<input id="invoice_items_attributes__item" type="text" size="30"
name="invoice[items_attributes][][item]"/>
<label for="invoice_items_attributes__quantity">quantity</label>
<input id="invoice_items_attributes__quantity" type="text" size="30"
name="invoice[items_attributes][][quantity]"/>
<label for="invoice_items_attributes__price">Price</label>
<input id="invoice_items_attributes__price" type="text" size="30"
name="invoice[items_attributes][][price]"/>
<a onclick="this.up('.invoice_item').remove(); return false;"
href="#">remover</a>
</div>
<div class="invoice_item">
<label for="invoice_items_attributes__item">item</label>
<input id="invoice_items_attributes__item" type="text" size="30"
name="invoice[items_attributes][][item]"/>
<label for="invoice_items_attributes__quantity">quantity</label>
<input id="invoice_items_attributes__quantity" type="text" size="30"
name="invoice[items_attributes][][quantity]"/>
<label for="invoice_items_attributes__price">Price</label>
<input id="invoice_items_attributes__price" type="text" size="30"
name="invoice[items_attributes][][price]"/>
<a onclick="this.up('.invoice_item').remove(); return false;"
href="#">remover</a>
</div>
<div class="invoice_item">
<label for="invoice_items_attributes__item">item</label>
<input id="invoice_items_attributes__item" type="text" size="30"
name="invoice[items_attributes][][item]"/>
<label for="invoice_items_attributes__quantity">quantity</label>
<input id="invoice_items_attributes__quantity" type="text" size="30"
name="invoice[items_attributes][][quantity]"/>
<label for="invoice_items_attributes__price">Price</label>
<input id="invoice_items_attributes__price" type="text" size="30"
name="invoice[items_attributes][][price]"/>
<a onclick="this.up('.invoice_item').remove(); return false;"
href="#">remover</a>
</div>
</div>

Or you can see the code here: http://pastie.org/339225

The question is: Should this input(<input
id="invoice_items_attributes__item" type="text" size="30"
name="invoice[items_attributes][][item]"/>) have a id different from the
other ones? I'm using a partial (partial code: http://pastie.org/334967)
to render this output. What should I do?

Sorry for all those question, but I'm a little noobe, and I have
exhausted all other sources that I now.

Thanks,

David S.
David S. (Guest)
on 2008-12-15 18:16
So, now I know where is the error, but I still don't know how to fix it.

When I use remote_form_for, the params hash gets messed up. If I use,
form_for, everything is sent ok. But, I want a Ajax for.

Does anyone know how to fix it?

thanks,


David S.
Hassan S. (Guest)
on 2008-12-15 18:32
(Received via mailing list)
On Sun, Dec 14, 2008 at 5:14 PM, David S.
<removed_email_address@domain.invalid> wrote:

> The question is: Should this input(<input
> id="invoice_items_attributes__item" type="text" size="30"
> name="invoice[items_attributes][][item]"/>) have a id different from the
> other ones? I

Absolutely, that's basic HTML -- an ID must be unique within a given
page. And more so if you have JavaScript acting on things via ID.

FWIW,
--
Hassan S. ------------------------ removed_email_address@domain.invalid
David S. (Guest)
on 2008-12-16 03:50
Hi Hassan S.,
thanks for replay it.

So, to solve the problem I had to create a unique ID to each element.
That was easy I used this code:

<% fields_for "invoice[items_attributes][#{Time.now.tv_usec.to_s}]",
invoice_item  do |form_invoice_item| -%>

And with Time.now.tv_usec.to_s I created a unique ID for each group of
elements, and e got the params hash like this:

Parameters: {"commit"=>"Cadastrar", "invoice"=>{"mode"=>"in",
"items_attributes"=>{ "239625"=>[{"price"=>"2", "should_destroy"=>"",
"quantity"=>"2", "id"=>"109", "item"=>"2"}],
                      "48717"=>[{"price"=>"5", "quantity"=>"5",
"item"=>"5"}],
                      "238297"=>[{"price"=>"1", "should_destroy"=>"",
"quantity"=>"1", "id"=>"108", "item"=>"1"}],
                      "240939"=>[{"price"=>"4", "should_destroy"=>"",
"quantity"=>"4", "id"=>"110", "item"=>"4"}],
                      "236847"=>[{"price"=>"3", "should_destroy"=>"",
"quantity"=>"3", "id"=>"107", "item"=>"3"}]},
"total"=>"123", "id"=>"45", "company_id"=>"10"},
"authenticity_token"=>"560d84898abf599368ad8ef6972ffbb649ecf0ee"}
( http://pastie.org/340083 ).

But I got a problem when accessing those attributes in  my model.
It was like this:
...
items_attributes.each do |attributes|
  invoice_item.build(attributes)
...
and I have to add a [1] to access the right attributes.
...
items_attributes.each do |attributes|
  invoice_item.build(attributes[1])
...

The attributes[0] give me = 239625, and
    attributes[1] = price2should_destroyquantity2id109item2

To create I new record, every thing was ok.
To edit, I have to access the ID of the attributes variable... and I
don't know how. I have tried attributes[1][:id], attributes[1][0],
attributes[1][id].
Nothing seems to work. My model source code is here:
http://pastie.org/340088

So to sum up, how can I access the Id attributes of attributes[1]

Thanks

David S.
Frederick C. (Guest)
on 2008-12-16 13:35
(Received via mailing list)
On Dec 16, 1:50 am, David S. <removed_email_address@domain.invalid>
wrote:
> Hi Hassan S.,
> thanks for replay it.
>
> So, to solve the problem I had to create a unique ID to each element.
> That was easy I used this code:
>
> <% fields_for "invoice[items_attributes][#{Time.now.tv_usec.to_s}]",
> invoice_item  do |form_invoice_item| -%>
>
If the forms you had right at the beginning only submitted incorectly
because of the duplicate ids then I'd try going back to that original
code and only changing
<%= form_invoice_item.text_field :item %>
to
<%= form_invoice_item.text_field :item, :id =>
"invoice_items_attributes_item_#{invoice_item.id}" %>

Fred
This topic is locked and can not be replied to.