Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the id of the object when inside form_for or fields_for

I have the following code that is generating fields for an invoice

THis is in the edit.html.erb for the invoice class

<% f.fields_for(:invoice_items)  do |f| %>
    <%= render :partial => 'invoice_items/fields', :locals => {:f => f} %>
<% end %>

and I generate the invoice_items as part of the invoice object

@invoice = Invoice.find(params[:id], :include => :invoice_items, :order =>"invoice_items.display_order")

It works just fine, but I need to wrap each one in a div, and assign that object's id to the div. (div id=i_2345 - that kind of thing) so I can use jQuery wizardry.

Where I am stumbling like a new-born foal is how do I access the the id of the invoice_item that is being called?

I can do a f.text_field :id and it gives me the correct id - so it knows it. But I am hoping there is some rails magic pixie dust I can sprinkle that will give it to me without having to rip that apart.

like image 494
Ben R Avatar asked Jan 20 '10 13:01

Ben R


2 Answers

I found the answer:

f.object.id
like image 106
Ben R Avatar answered Oct 17 '22 23:10

Ben R


f.index

You might want to use f.index instead of f.object.id.

When you call f.object.id you are getting the id of the object that the form is referencing. That is fine when the object is already saved, but sometimes it isn't (For example, in your case, when you are using fields_for and are creating new InvoiceItems for your Invoice. Those InvoiceItems don't exist yet, so they don't have an id)

In such cases, Rails form helpers creates this index that is used to pass multiple objects inside an array without overwriting anything. That's why if you check your form you might see the input has and id like:

id=invoice_invoice_items_attributes_1586974556130_display_order

And a name like:

name=invoice[invoice_items_attributes][1586974556130][display_order]

The number 1586974556130 here is the index created by rails so it can send the form with multiple invoice_items_attributes inside an array. If the object is saved, however, the f.index will return the id of the object, so it will create the appropriate tags such as [invoice_items_attributes][1]. You should be calling f.index instead, it will return the id of the object when it saved, otherwise, it will return the index created by rails.

You jQuery wizardry could access this:

$("#invoice_invoice_items_attributes_<%= f.index %>_display_order")

Reference: https://api.rubyonrails.org/v6.0.2.1/classes/ActionView/Helpers/FormBuilder.html

Hope it helps!

like image 30
Lucas Kuhn Avatar answered Oct 17 '22 22:10

Lucas Kuhn