2014-09-25 27 views
3

我有这些关系复杂的类别下拉取决于当前的叶节点上

User 
has_many :products 
has_many :stores 

Product 
belongs_to :user 
belongs_to :store 
belongs_to :category 

Store 
belongs_to :user 
has_many :products 

Category 
acts_as_nested_set 
has_many :products 

在主页(查看文件),我有一个分类下拉类似亚马逊的:

<ul id="site-category-dropdown"> 
      <li class="has-dropdown"> 
       <a href="#"> 
        <span class="site-category-dropdown-link-span"> 
         <span class="line-1">SHOP BY</span> 
         <span class="line-2">Category</span> 
        </span> 

       </a> 
       <ul class="dropdown dropdown-box-shadow"> 
        <% Category.all.each do |root_cat| %> 
         <li class="has-dropdown site-category-dropdown-element"> 
          <a href="#" class="site-category-dropdown-element-link"> 
           <span class="term"><%= root_cat.name %></span> 
          </a> 
           <ul class="dropdown"> 
            <% root_cat.children.each do |children| %> 
             <li><%= link_to children.name, category_path(id: children.id) %></li> 
            <% end %> 
          </ul> 
         </li> 
        <% end %> 
       </ul> 
      </li> 
     </ul> 

这看起来像下面的图像(根类别和其子类别显示在悬停) Site category dropdown

现在我在商店页面上,我想展示一个类似于网站下拉菜单的下拉菜单,但仅限于商店正在销售的产品。
商店产品

Product 1 - (category_id: 46, store_id: 1, product_name: "Prada t-shirt") 
Product 2 - (category_id: 47, store_id: 1, product_name: "Prada shoes") 
Product 3 - (category_id: 47, store_id: 1, product_name: "Gucci shoes") 
Product 4 - (category_id: 12, store_id: 1, product_name: "A classy Dining Table") 
Product 5 - (category_id: 12, store_id: 1, product_name: "Kitchen stool") 
Product 6 - (category_id: 12, store_id: 1, product_name: "Office Chair") 

<br> 
cateogory_id 46 is T-shirt in Fashion -> Men -> T-shirt 
<br> 
category_id 47 is Shoe in Fashion -> Men -> Shoe 
<br> 
category_id 12 is Furniture in Home -> Furniture 
<br> 

我使用awesome_nested_set宝石的类别(https://github.com/collectiveidea/awesome_nested_set
我可以在阵列中使用映射所有CATEGORY_ID: category_ids = @ store.products.map(&: category_id)

我的问题是,我如何构建一个类似于我上面显示的网站下拉菜单的下拉菜单,但仅限于此商店销售的产品。请记住,每个产品的category_id都是叶类别的类别ID,我如何从根类别重新创建下拉菜单?使用上面给出的商店产品,它应该看起来像这样: Store category drop down, only products sold by the store.

+0

你知道这将执行多少个查询吗?我现在无法帮助您回答问题。我只想指出我能看到的极端n + 1问题(例如,1个查询收集所有类别,然后x查询这些类别的孩子,然后可能x个针对这些孩子的查询)随着事情扩大这会对性能产生很大的影响。 – engineersmnky 2014-09-25 16:50:34

+0

是的,这是问题所在。我只是想知道是否有人以前解决过这类问题。 – Skyalchemist 2014-09-25 17:14:55

+0

你可以这样做:'Category.self_and_descendants'只是确保你的类别层次结构只是类似于:'home - > furniture - > table'或'Fashion - > men - > t-shirt - >(品牌名称) – Surya 2014-09-25 17:26:04

回答

2

这可能是一个天真的实现,但我认为它可以做到这一点。

# in your controller 
@categories = find_root_categories @store.products.map(&:category_id) 

def find_root_categories(leaf_categories) 
    leaf_categories.map { |node| find_root(node) }.uniq! 
end 

def find_root(leaf) 
    return leaf unless leaf.parent_id? 
    find_root(Category.find(leaf.parent_id)) 
end 

然后你会像在原始文章中一样遍历集合。这确实会招致@engineersmnky警告的开销,因为你会进行大量的数据库调用。这可能是一个好主意,打电话之前find_root缓存在一个实例变量的所有类别:

# in the controller 
@categories = Category.all 

def find_root(leaf) 
    return leaf unless leaf.parent_id? 
    find_root(@categories.find(leaf.parent_id)) 
end 

请让我知道如果我误解了一些关于你的问题!

相关问题