0

How to create form and action for multiple nested attributes if:

LineItem:

has_many :item_options, :dependent => :destroy
has_many :product_options, :through => :item_options

ProductOption:

belongs_to :product
belongs_to :option
has_many :item_options
has_many :line_items, :through => :item_options

ItemOption:

attr_accessible :line_item_id, :product_option_id  
belongs_to :line_item, :foreign_key => "line_item_id"
belongs_to :product_option,:foreign_key => "product_option_id"

When I'm creating new LineItem, I need to create new ItemOption(s). This is my form:

        <%= form_for(LineItem.new) do |f| %>
        <%= f.hidden_field :product_id, value: @product.id %>
        <%= f.fields_for :item_options do |io| %>
            <% @product.options.uniq.each do |o| %>
              <%= o.name %>: 
              <%= io.collection_select :product_option_id, o.product_options.where(:product_id => @product.id), :id, :value %>
            <% end %>
        <%= f.submit %>
        <% end %>

When I'm clicking on Add To Cart, I've get:

ItemOption(#70296453751440) expected, got Array(#70296430421140)

When Adding accepts_nested_attributes_for :item_options to LineItem, my selects not diplayed :(

With

<%= select_tag "product_option_id", options_from_collection_for_select(o.product_options.where(:product_id => @product.id), :id, :value) %>
#item_options not created:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"/WM5/MqPn1yCxjKWoJQmjfko2pR4RiYV0S2KeTTpA3w=", "line_item"=>{"product_id"=>"1"}, "product_option_id"=>"5", "commit"=>"add"}

And last one, I've create action like this:

@line_item = LineItem.new(params[:line_item])
@line_item.item_options.build 
....

Where am I wrong? :( I'm totally confused. ps. similar question Rails 3.2 has_many through form submission This is form:

1 Answer 1

1

Looks this line:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"/WM5/MqPn1yCxjKWoJQmjfko2pR4RiYV0S2KeTTpA3w=", "line_item"=>{"product_id"=>"1"}, "product_option_id"=>"5", "commit"=>"add"}

The parameter product_option_id is outside line_item hash, and will be inside. Maybe you need write the select like this:

<%= select_tag "line_item[product_option_id]", options_from_collection_for_select(o.product_options.where(:product_id => @product.id), :id, :value) %>

I'm not sure, but maybe is this. Maybe I need more information, like the exact line where is failing.


Extra, the :foreign_key => "line_item_id" and :foreign_key => "product_option_id" are not necesary, because, the belongs_to model name is the same and will use these foreign_key. From api.

Specify the foreign key used for the association. By default this is guessed to be the name of the association with an “_id” suffix. So a class that defines a **belongs_to :person** association will use “person_id” as the default :foreign_key. Similarly, belongs_to :favorite_person, :class_name => "Person" will use a foreign key of “favorite_person_id”.


Edit

Sorry, the unknown attribute: product_option_id is because the attribute name is product_option_ids, and is an array, not a unique value. For a has_many relationship, the column name is collection_singular_ids, and the select should be:

<%= select_tag "line_item[product_option_ids][]", options_from_collection_for_select(o.product_options.where(:product_id => @product.id), :id, :value) %>

This should work, I think :)...

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

4 Comments

Tnx, but unknown attribute: product_option_id ... In params: {"utf8"=>"✓", "authenticity_token"=>"ik5ad6KsTOD+b4e9ioenFqfXY1nojXdEGAeNAXlCN8E=", "line_item"=>{"product_id"=>"1", "product_option_id"=>"5"}, "commit"=>"Добавить в корзину"}
Maybe it's something like: <%= select_tag "item_option[product_option_id]", options_from_collection_for_select(o.product_options.where(:product_id => @product.id), :id, :value) %> But it's only one item_option, even have several in form :( Params: "line_item"=>{"product_id"=>"1"}, "item_option"=>{"product_option_id"=>"4"},
This variant is better: <%= select_tag "item_option[][product_option_id]", options_from_collection_for_select(o.product_options.where(:product_id => @product.id), :id, :value) %>, than in params: "line_item"=>{"product_id"=>"1"}, "item_option"=>[{"product_option_id"=>"1"}, {"product_option_id"=>"4"}]. But still not saving (
You have the column in your attr_accessible?, like attr_accessible :product_option_ids or attr_accesible :product_option_id. Edit, late :P

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.