Reputation: 49
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
Upvotes: 0
Views: 2241
Reputation: 42863
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
Upvotes: 2
Reputation: 26979
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.
Upvotes: 0
Reputation: 2606
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.
Upvotes: 0