views:

129

answers:

1

Hi

i have some Orders that can have several Items and these Items have an associated Kind. The Kind can belong to many Items. but i get a "unknown attribute: kinds" in my OrdersController when i hit the submit form button. I use nested forms btw.

Order.rb

class Order < ActiveRecord::Base
  validates_presence_of :ref_nr, :total_price

  has_many :items, :dependent => :destroy
  has_many :kinds, :through => :items

  accepts_nested_attributes_for :items
  accepts_nested_attributes_for :kinds

  validates_associated :items
  validates_associated :kinds


end

Item.rb

class Item < ActiveRecord::Base
  belongs_to :order
  has_one :kind

  accepts_nested_attributes_for :kind

  validates_associated :kind
end

Kind.rb

class Kind < ActiveRecord::Base
 belongs_to :items
end

OrdersController.rb:Create

def create
    @order = Order.new(params[:order])
end

new.erb.html

<% form_for @order do |f| %>
  <%= f.error_messages %>

  <% f.fields_for :items do |builder| %>
    <table>
    <tr>
      <% builder.fields_for :kinds do |m| %>
        <td><%= m.collection_select :kind, Kind.find(:all, :order => "created_at DESC"), :id, :name, {:prompt   => "Select a Type" }, {:id => "selector", :onchange => "kind_change(this)"} %></td>
    <% end %>
      <td><%= builder.text_field :amount, :id => "amountField", :onchange => "change_total_price()" %></td>
      <td><%= builder.text_field :text, :id => "textField" %></td>
      <td><%= builder.text_field :price, :class => "priceField", :onChange => "change_total_price()" %></td>
      <td><%= link_to_remove_fields "Remove Item", f %></td>
    </tr>
    </table>
    <% end %>
    <p><%= link_to_add_fields "Add Item", f, :items %></p>
    <p>
      <%= f.label :total_price %><br />
      <%= f.text_field :total_price, :class => "priceField", :id => "totalPrice" %>
    </p>
    <p><%= submit_tag %></p>
<% end %>

i cant see what im missing

+1  A: 

You should remove accepts_nested_attributes_for :kinds in Order model and it should be in Item model (as in your code). Then change view here:

...
<% f.fields_for :items do |builder| %>
  <table>
    <tr>
      <% builder.fields_for :kind do |m| %>
...

And I think that you have also mistake in following lines:

<td><%= f.text_field :amount, :id => "amountField", :onchange => "change_total_price()" %></td>
<td><%= f.text_field :text, :id => "textField" %></td>
<td><%= f.text_field :price, :class => "priceField", :onChange => "change_total_price()" %></td>

If fields amount, text and price are associated with Item model, then you should use builder instead of f:

<td><%= builder.text_field :amount, :id => "amountField", :onchange => "change_total_price()" %></td>
<td><%= builder.text_field :text, :id => "textField" %></td>
<td><%= builder.text_field :price, :class => "priceField", :onChange => "change_total_price()" %></td>

EDIT (to answer additional questions from comments):

You should have:

<% f.fields_for :items do |builder| %>
  <table>
    <tr>
      <td><%= builder.collection_select :kind_id, Kind.find(:all, :order => "created_at DESC"), :id, :name, {:prompt   => "Select a Type" }, {:id => "selector", :onchange => "kind_change(this)"} %></td>  
      <td><%= builder.text_field :amount, :id => "amountField", :onchange => "change_total_price()" %></td>
      <td><%= builder.text_field :text, :id => "textField" %></td>
      <td><%= builder.text_field :price, :class => "priceField", :onChange => "change_total_price()" %></td>

and so on...

klew
I am using builder im just rendering another view and passing f as builder. <%= render "item_fields", :f => builder %>thats my bad. Should have made that clear.Anyways. removing the accepts_nested_attributes_for :kinds from the Order model did not do the trick :(
Flexo
Ok, in form it's not `fields_for :kinds` but `fields_for :kind`
klew
That worked wonders, but now my collection_select does not show..
Flexo
Yea, it shoudn't work :). If you want to create a select field to select a kind that is assigned to item, then you should remove `builder.fields_for :kind` with it's contents and just add `builder.collection_select :kind_id ...` where the rest is what you have in example. However I'm not sure if it should be `:kind_id` or just `:kind`.
klew
You should use this version with `fields_for :kind` if you want to add/edit/remove a kind through this form.
klew
Thank you very much.. 2 thumbs up for all your help :)
Flexo
Just one last question, when i remove the fields_for and just use builder, i get an "AssociationTypeMismatch"Kind(#69935645277820) expected, got String(#69935679589380)
Flexo
I've edited my answer. Take a look on it.
klew
Thank you very much
Flexo