如何实现同一模型的嵌套实例?例如。一个类别中的类别?

时间:2012-12-21 01:38:33

标签: ruby-on-rails ruby-on-rails-3

我有一个category模型,基本上是products分配的模型。

所以我的category模型看起来像这样:

attr_accessible :name
has_many :category_products do
  def with_products
    includes(:product)
  end
end

has_many :products, :through => :category_products

我想要做的是在类别中添加类别 - 因此产品应该能够放入Men然后Shoes

这样,我可以有一个Men下拉菜单,可以生成Men中的所有子类别,例如Shoes

但是,如果用户点击Men,他们就会看到该类别中的所有产品。

思想?

2 个答案:

答案 0 :(得分:2)

您可以使用像Ancestry这样的宝石来将您的类别组织到一个层次结构中。

如果您只需要一层深度的嵌套,则可以使用自联接。

belongs_to :parent_category, class: "Category"
has_many :subcategories, class: "Category"

您还需要迁移才能将category_id添加到category表格。

app/views/categories/_form.html.erb下拉到category_id并在其中填入您的类别列表。您可以使用此选项为您的类别选择“父级”。

然后你可以做类似的事情:

# Get parent category's name
<%= somecategory.parent.name %>

# Iterate through subcategories
<% someothercategory.subcategories.each do |category| %>
  <%= category.name %>
<% end %>

使用像Ancestry这样的宝石,在处理这些类别及其关联时会给你更大的灵活性。

关于祖先是如何运作的:

  

Ancestry存储每个节点从根到父节点的路径。   这是物化路径数据库模式的变体。它   允许Ancestry获取任何关系(兄弟姐妹,后代等)   单个SQL查询没有复杂的算法和   与左右值相关的不可理解性。   此外,任何插入,删除和更新仅影响节点   在受影响的节点自己的子树中。

答案 1 :(得分:0)

我不知道Ancestry gem如何运作,但在嵌套解决方案中主要关心的是 - 速度。 如果模型类别不受高频创建的影响,请尝试awesome_nested_set。它不仅使用parent_id,而且还使用:lft和:rgt列,这些列显着加快了相互嵌套对象的搜索速度,当孩子非常非常多时...... 30-50个类别和数千种产品 - 其中一种情况。 / p>