首页 > 解决方案 > Rails 使用引用自身的表创建分组无序列表?

问题描述

我有一个如下所示的类别表:

id store_id parent_category_id name
1  1        nil                Footwear
5  1        1                  Men's Shoes
7  2        nil                Accessories
22 2        7                  Watch

我想要做的是根据与类别的关联(如果它们匹配)在我的索引页面上创建一个过滤器。我苦苦挣扎的地方是让小组/分类为设计工作。我要显示的内容如下:

p {
display: inline-block;
padding-left: 10px;
}
<ul class="nav">
    <li class="nav-item active">
      <a href="#homeSubmenu1" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle">Footwear</a>
      <p>2,000</p>
      <ul class="collapse list-style-upper" id="homeSubmenu1">
        <li><a href="home-sub-submenu1">Men's Shoes</a>
        <p>1,000</p>
          <ul class="list-style-upper-sub">
            <li>Adidas<p>1,000</p></li>
            <li>Nike<p>500</p></li>
            <li>Convers<p>500</p></li>
          </ul>
        </li>
        <li><a href="#">Women's Shoes</a><p>500</p></li>
        <li><a href="#">Children's Shoes</a><p>500</p></li>
        <li><a href="#">Socks<p>100</p></a>
          <ul class="list-style-upper-sub">
            <li>Blue<p>50</p></li>
            <li>Red<p>25</p></li>
            <li>Green<p>25</p></li>
          </ul>
        </li>
      </ul>

到目前为止,我已经构建了 parent 方法来捕获基于 nil 的父母:

def parent_category
 Connector::Category.where(parent_category_id: [nil, ''])
end

这会引入正确的父母,但我不太清楚如何按 parent_category_id 分组,然后应用正确的链接来应用过滤。我试过这样的事情:

<ul class="nav">
 <% Connector::Category.group(:name).each do |x|%>
   <li><%=x.name.titleize%></li>
 <%end%>
</ul>

这会导致 PG::GroupingError: ERROR: column "connector_categories.id" 必须出现在 GROUP BY 子句中或在聚合函数中使用。

所以我想我会把它放在产品索引页面(出现的地方)的 index 方法上,如下所示:

def index
 query = query_products
 query = query.search(params[:search]) if params[:search]
 @products = query.order(sortable_query).paginate(page: params[:page], per_page: 20)
 @category = Connector::Category.select(:id, :name).all.order('number ASC').group(:parent_category_id)
end
<ul class="nav">
  <%@category.all.each do |X|%>
   <li><%=x.name%></li>
  <%end%>
</ul>

这导致形式参数不能是常数。

那么如何使用引用自身的表创建分组无序列表呢?

标签: ruby-on-rails

解决方案


谈论显示类别树。我建议不要使用对数据库进行分组来构建复杂的查询,而是使用 SINGLE 普通SELECT查询获取所有类别并以编程方式构建嵌套树,例如:

@categories = Connector::Category.includes(:products).group_by { |category| category.parent_category_id }

因此,根类别(没有父类别)将作为@categories[nil]. each您可以在此列表上使用 -loop开始显示类别树。对于每个根类别cat,其子类别的列表可以作为@categories[cat.id].

由于类别树的嵌套可能很深(可能有孩子、孙子、孙子等),我建议创建一个部分来显示给定类别的孩子并递归调用它。例子:

# _category_item.html.erb

<li>
  <a href="#"><%= category.name =><p><%= category.products.count %></p></a>
  <% if @categories[category.id].present? %>
    <ul class="list-style-upper-sub">
      <% @categories[category.id].each do |child| %>
        <%= render 'category_item', category: child %>
      <% end %>
    </ul>
  <% end %>
</li>

在主视图中:

# index.html.erb

<ul class="list-style-upper">
  <% @categories[nil].each do |root| %>
    <%= render 'category_item', category: root %>
  <% end %>
</ul>

题外话:如果有循环,递归渲染类别树可能会失败:例如,类别 A 是类别 B 的父级,而后者又是类别 A 的父级,或者类别 A 是其自身的父级。您需要确保树没有这样的循环。


推荐阅读