产品 - 分类协会。 (编辑)belongs_to,has_and_belongs_to_many?

时间:2010-09-05 20:00:40

标签: ruby-on-rails

我为此目的创建了一个联接表。这是代码:

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

产品型号:

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

和类别模型:

class Category < ActiveRecord::Base
  has_and_belongs_to_many :products
end

到目前为止一切顺利。问题出在form.html.erb上。 代码在这里:

<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>

我尝试在选择框中加载类别但是我收到一条消息“未定义的方法`category_id'用于#”。

我不明白为什么?我也尝试过has_many:通过但同样的事情发生了。

我应该能够以这种方式绘制类别,因为它们是相关联的,但我不是。有什么想法吗?

我尝试了railscast.com的screancast,但没有运气。您是否考虑过产品类别,子类别关联的完整教程/示例?我还没有找到一个下降的(除了railscast,但这对我不起作用)。

非常感谢您的时间,感谢您回答的麻烦(如果您这样做的话)。

编辑:我发现产品型号存在问题。这是修复:

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

编辑2:我的类别也有另一个问题。

类别名称不会出现在视图中。我调用了category_name函数,但我得不到任何回报。像这样(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>

或(show.html.erb):

<td><%= product.category_name %></td>

我尝试更改为has_and_belongs_to_many :categories,至少我收回了“类别”作为一个奇怪的名字......因为我有4个类别。

产品只属于一个类别。

PS:再次,谢谢你的时间。

2 个答案:

答案 0 :(得分:0)

<%= f.collection_select :category_id ... %>

该行正在表单对象上查找.category_id,该表单对象具有依赖于为其创建表单的对象的访问器(我假设它是一个产品对象)。产品对象具有has_and_belongs_to_many与类别的关系的属性,但它不是单个类别ID。可用的方法列于here。我不确定因为我没有使用has_and_belongs_to_many,但我认为你会想要

<%= f.collection_select :categories_singular_ids ... %>

collection_select需要是一个多选项,因此对于你的html,你需要在最后一个选项哈希中:multiple => true

答案 1 :(得分:0)

尝试以下方法:

<%= f.select :category_ids, Category.pluck(:name, :id), { prompt: "Select a Category" }, multiple: true %>

不要忘记允许category_ids,即: params.require(:product).permit(category_ids: [])