ruby-on-rails - 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>
这导致形式参数不能是常数。
那么如何使用引用自身的表创建分组无序列表呢?
解决方案
谈论显示类别树。我建议不要使用对数据库进行分组来构建复杂的查询,而是使用 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 是其自身的父级。您需要确保树没有这样的循环。
推荐阅读
- javascript - 用玩笑和酶错误反应应用程序测试
- java - JAVA:程序在终端中工作,但不在 Visual Studio 代码中:Mac OS
- python - 基于正则表达式的熊猫数据框条件
- android - 未检测到原始图像 ExifInterface
- vue.js - 如何在 vuejs 中克隆数据?
- android - 如何在 Android 中使用 LocationMarnager#getCurrentLocation
- android - 如何使用 Android MediaPlayer 按字节块播放音频数据
- ios - 如何解决保存在表格视图上显示的数据的问题?
- python - 为什么不能在 python 中得到总数?
- html - 我不明白网格 CSS 在做什么