0

I'm a rails and ruby noob, and Im pretty sure this something completely stupid I am missing..

Trying to build a nested form, and have found many examples online, and tried and failed to reproduce the desired result.

the "seller" fields are not even displayed, and when I submit form I get:

unknown attribute: item

models:

class Dealerform < ActiveRecord::Base
 belongs_to :dealer
 has_one :seller :class_name => 'Seller'
 has_many :items, :through => :seller
 accepts_nested_attributes_for :seller, :items

end

class Seller < ActiveRecord::Base
 belongs_to :dealerform
 has_many :items :class_name => 'Item'
end

class Item < ActiveRecord::Base
 belongs_to :seller
end

view:

<% form_for(@dealerform) do |f| %>
<%= f.error_messages %>
 <p>
 <%= f.label :date %><br />
 <%= f.datetime_select :date %>
 </p>
      #...more fields ...

<% f.fields_for :seller do |seller| %>

<p>
 <%= seller.label :fname %><br />
 <%= seller.text_field :fname %>
</p>
      #...more fields ...

<% end %>

 <% f.fields_for :item do |item| %>
  <p>
   <%= item.label :foo %><br />
   <%= item.text_field :foo %>
  </p>
      #...more fields ...

 <% end %>

<%= f.submit 'Create' %> 
<% end %>

Based on suggestions.. changed the following lines:

<% f.fields_for :seller do |seller| %>
<% f.fields_for :item do |item| %>

to:

<% f.fields_for @seller do |seller| %>
<% f.fields_for @item do |item| %>

and now they show up in the form, and when trying to submit form I get:

unknown attribute: nil_class

when I change:

def new
  @dealerform = Dealerform.new

to:

def new
  @dealerform = Dealerform.new
  @dealerform.seller.build

I get:

undefined method `build' for nil:NilClass

2
  • Hints: Please don't begin sentences with "so". Please begin sentences with Capital Letters. Please capitalize "I". Commented Oct 23, 2010 at 18:31
  • Reminder — if you're working in Rails 3.0.0 or 2.3.9, be sure to upgrade now, since there is a security vulnerability for accepts_nested_attributes_for. Commented Oct 23, 2010 at 18:33

3 Answers 3

2

It's because the fields_for attribute wil only display resources that exist. In your controller you need to build objects for the forms to containe.

So in your controller

def new
    #2.times {@dealer_form.items}
    @dealer_form = DealerForm.new
    @dealer_form.seller = Seller.new
    #or @dealer_form.seller.build
end 
Sign up to request clarification or add additional context in comments.

7 Comments

made this change and now get: undefined method `build' for nil:NilClass
It just means that you are building something that doesn't exist.
check your associations. You have too many for me to go over each and if I did I'm not sure you declared all of them correctly. Just make sure sellers is actually a has_many and so on... :)
@Sam: this is the result I'd expect from @dealer_form.seller.build. If there is no seller defined yet, @dealer_form.seller will return nil, right? Or is there some Ruby duck typing there that I haven't dealt with before?
I don't really know. Its sounds like you got more than a simple thing setup. Start with a really simple association and then move from there. As for the nil error your getting it just means that your associations are wrong.
|
0

It looks like your dealerform model has_many items but your fields_for is submitting a singular item, so when it tries to initialize your dealerform in the create action it's trying to assign dealerform.item but there's no such method. If a dealerform has many items you may want to check out this example http://media.pragprog.com/titles/fr_arr/multiple_models_one_form.pdf for how to manage the has_many in a single form.

Comments

0

As Sam indicated, you ned to have an actual object, whether new or existing:

f.fields_for @seller

You can get @seller in several different ways, using build to create a new one, or if you are editing an existing record, use @dealerform.seller.

In the case of items, you may need to loop over several, depending on how many form you want to display. Check out http://www.railscasts.com for some screencasts on this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.