2

I have a nested form in a rails view that is called like this

<% f.fields_for :invoice_item_numbers do |item_no_form| %> <%= render 'invoice_item_number', :f => item_no_form %> <% end %> 

and the partial (_invoice_item_number.html.erb) looks like this

<div class='invoice_item_numbers'> <% if f.object.new_record? %> <li><%= f.label :item_number %><%= f.text_field :item_number %> <%= link_to_function "remove", "$(this).parent().remove()", :class => 'remove_link' %></li> <% else %> <li class="inline"><%= f.label :item_number %><%= f.text_field :item_number %> </li><li class="inline"><%= f.label :description %><%= invoice_item_number.description %></li><li><%= f.label :amount %><%= f.text_field :amount %> <%= f.check_box '_destroy', :class => 'remove_checkbox' %> <%= f.label '_destroy', 'remove', :class => 'remove_label' %></li> <% end %> </div> 

This fails with the error message

undefined method `description' for nil:NilClass 

Why does invoice_item_number return a nil object in this partial? It is obviously being defined somehow because if I change it to something else (e.g. item_number.description then the error message becomes undefined local variable or methoditem_number' for #instead. The invoice_item_number object that is being displayed by this partial is being used perfectly well by the form helpers as<%= f.text_field :item_number %>and<% f.text_field :amount %>both work perfectly well. I have tried a number of solutions such as using@invoice_item_number` and explicitly defining an object in the render method but these have not worked.

Presumably there is a very simple answer to this.

2 Answers 2

6

Just re-read the Ryan's scraps post on nested forms at http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes and found the answer. It was sort of in my code already but I didn't understand what was happening. I can access the invoice_item_number object with f.object so replacing <%= invoice_item_number.description %> with <%= f.object.description %> solved my problem.

Sign up to request clarification or add additional context in comments.

2 Comments

No problem. I'm grateful you took the time to read it. Thanks.
is it me or are the majority of the 'famous' rails developers named Ryan? Ryan Bigg, Ryan Bates, Ryan Daigle.. wtf hahah
2

how about changing:

<%= invoice_item_number.description %> 

to

<%= f.label :description %> 

or if you need a field:

<%= f.text_field :description %> 

4 Comments

Well, I've already got f.label :description in there. Interestingly, if I do put in f.text_field :description this accesses the description method exactly as I want, but I don't want a text field, I just want the text. Thanks though.
invoice_item_number is nil (not defined yet) in the partial. if you want to access the model data, you needed to define @invoice_item_number in the controller and access by @invoice_item_number.description
Hmm, but invoice_item_number is a nested attribute in this case. The parent attribute (invoice) is defined in the controller with @invoice=Invoice.find(params[:id]). What I really want to access is invoice.invoice_item_number.description but I'm not sure how to in my partial.
you can pass multiple parameters to a partial, the syntax is: <%= render :partial => 'invoice_item_number', :locals => { :f => item_no_form, :x => 123 } %> then you can use x as a local variable inside the partial.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.