Products - Categories association. (edit) belongs_to, has_and_belongs_to_many?
I created a joined table f开发者_JAVA技巧or the purpose. Here's the code:
class CreateCategoriesProductsJoin < ActiveRecord::Migration
def self.up
create_table 'categories_products', :id => false do |t|
t.column 'category_id', :integer
t.column 'product_id', :integer
end
end
def self.down
drop_table 'categories_products'
end
end
The Product model:
class Product < ActiveRecord::Base
has_and_belongs_to_many :categories
attr_accessor :new_category_name
before_save :create_category_from_name
def create_category_from_name
create_category(:name => new_category_name) unless new_category_name.blank?
end
end
And the category model:
class Category < ActiveRecord::Base
has_and_belongs_to_many :products
end
So far so good. The problem is with the form.html.erb. code here:
<p>
<label for="product_category_id">Category:</label><br />
<%= f.collection_select :category_id, Category.find(:all), :id, :name, :prompt => "Select a Category" %>
or create one:
<%= f.text_field :new_category_name %>
</p>
I try to load the categories in a selection box but I get a message "undefined method `category_id' for #".
I don't understand why? I also tried with has_many :through but the same thing happened.
I should be able to draw the categories out with that way since the are associated but I'm not. Any ideas?
I tried the screancast from railscast.com but no luck. Do you have in mind a full tutorial/example with product category, subcategory associations? I haven't found a descend one yet ( except for the railscast but that doesn't work for me ).
Thank you very much for your time and thank you for the trouble it took you to respond ( if you did ).
Edit: I found the problem it was in the product model. Here's the fix:
class Product < ActiveRecord::Base
belongs_to :category
def category_name
category.name if category
end
def category_name=(name)
self.category = Category.find_by_name(name) unless name.blank?
end
end
Edit 2: I also have another problem with the categories.
Categories name doesn't appear in the view. I call the category_name function but I get nothing in return. Like this (show.html.erb):
<p>
<label for="product_category_id">Category:</label><br />
<%= f.collection_select :category_name, Category.find(:all), :id, :name, :prompt => "Select a Category" %>
or create one:
<%= f.text_field :new_category_name %>
</p>
Or (show.html.erb):
<td><%= product.category_name %></td>
I tried to change to has_and_belongs_to_many :categories
and at least I got back "Category" as a name which is weird... because I have 4 category.
A products belongs only to one category.
PS: Again, thank you for your time.
<%= f.collection_select :category_id ... %>
That line is looking for .category_id
on the form object, which has accessors dependent on the object the form was created for (I'm assuming it is a product object). The product object has attributes for the has_and_belongs_to_many
relationship with category, but it is not a single category id. The methods available are listed here. I'm not certain because I don't ever use has_and_belongs_to_many
, but I think you'll want
<%= f.collection_select :categories_singular_ids ... %>
The collection_select will need to be a multi-select, so for your html you'll want :multiple => true
in the last options hash.
Try to the following:
<%= f.select :category_ids, Category.pluck(:name, :id), { prompt: "Select a Category" }, multiple: true %>
Don't forget to permit category_ids
, ie:
params.require(:product).permit(category_ids: [])
精彩评论