如何获取HABTM关联的所有记录

时间:2014-05-26 01:40:29

标签: sql ruby-on-rails ruby

我有一个模型产品has_and_belongs_to_many类别。

设置类别表,以便顶级类别可以具有无限数量的子类别,看起来像这样

+----+------------------------+-----------+--------------+--+
| id |          name          | parent_id | top_level_id |  |
+----+------------------------+-----------+--------------+--+
|  1 | "Furniture"            |           |              |  |
|  2 | "Decor"                |           |              |  |
|  3 | "Lifestyle "           |           |              |  |
|  4 | "Electronics"          |           |              |  |
|  5 | "Sofas & Beds"         |         1 |            1 |  |
|  6 | "Chairs"               |         1 |            1 |  |
|  7 | "Tables"               |         1 |            1 |  |
|  8 | "Dressers & Wardrobes" |         1 |            1 |  |
|  9 | "Shelving & Storage"   |         1 |            1 |  |
| 10 | "Sofas"                |         5 |            1 |  |
| 11 | "Beds"                 |         5 |            1 |  |
| 12 | "Chaises"              |         5 |            1 |  |
+----+------------------------+-----------+--------------+--+

我希望能够查询"家具"的所有产品。例如,获取所有产品"家具"子类别。如果我查询了#34; Sofas&床"我想让所有的子猫喜欢"沙发"和"床"

这是我遍历此Categories表的方法。这只是为了构建菜单来显示和选择所有类别。我不认为它对你有多大帮助,但我想我会把它包括在内,让你知道我是如何使用它的。

module CategoryHelper

  def categories
    furniture = Category.where("top_level_category = ?", "1")
    decor = Category.where("top_level_category = ?", "2")
    lifestyle = Category.where("top_level_category = ?", "3")
    electronics = Category.where("top_level_category = ?", "4")

    def build_category_tree(top_level_category)
      categories = ""
      subcategories = ""
      top_level_category.each do |category|
        if category.parent_id == category.top_level_category
          categories << "<li class=\"shop_dropdown_category\" data-category=\"#{category.name}\"><a href=\"/category/#{category.id}\">#{category.name}</a><ul >"
          category_id = category.id
          subcategories = ""
          top_level_category.each do |subcategory|
            if category_id == subcategory.parent_id
              subcategories << "<li data-category=\"#{subcategory.name}\"><a href=\"/category/#{subcategory.id}\">#{subcategory.name}</a></li>"
            end
          end
          categories << subcategories << "</ul></li>"
        end
      end
      categories.html_safe
    end

    @furniture = build_category_tree(furniture)
    @decor = build_category_tree(decor)
    @lifestyle = build_category_tree(lifestyle)
    @electronics = build_category_tree(electronics)

  end

end

1 个答案:

答案 0 :(得分:0)

Ancestry

您首先想到的是ancestry gem - 这样您就可以根据需要将多个类别与parents / ancestors相关联:

#app/models/category.rb
Class Category < ActiveRecord::Base
   has_ancestry 
end

这应该允许你创建一个这样的表:

+----+------------------------+-----------+
| id |          name          | ancestry  |
+----+------------------------+-----------+
|  1 | "Furniture"            |           |
|  2 | "Decor"                |           |
|  3 | "Lifestyle "           |           |
|  4 | "Electronics"          |           |
|  5 | "Sofas & Beds"         |         1 |
|  6 | "Chairs"               |         1 |
|  7 | "Tables"               |         1 |
|  8 | "Dressers & Wardrobes" |         1 |
|  9 | "Shelving & Storage"   |         1 |
| 10 | "Sofas"                |       1/5 |
| 11 | "Beds"                 |       1/5 |
| 12 | "Chaises"              |       1/5 |
+----+------------------------+-----------+

根据docs,您可以使用它来调用Ancestry的一些内置方法,包括:

@category.child_ids

菜单

然后,您可以使用我们使用的以下代码重新定义菜单来备份它:

#app/views/categories/index.html.haml
/ Items
= render partial: "category", locals: { categories: @categories }

-

#app/views/shared/_category.html.haml
%ol{ class: "categories" }
    - categories.each.each do |category, sub_item|
        %li
            / Category
            .category
                = link_to category.title, category_path(category)


            / Children
            - if category.has_children?
                = render partial: "category", locals: { categories: category.children }