我有下表:产品,类别,ProductCategory。
我试图在分支结构中显示以下内容:
Accessories - 5,000
Men's Watches - 2,000
Tag Huer - 1,000
Samsung - 1,000
Women's Watches - 3,000
我遇到的问题是我的查询使应用程序变慢。我有以下查询:
def category_level
Connector::Category.includes(:products).group_by(&:parent_category_id)
end
然后在我看来,我有以下内容:
<ul class="list-style-upper">
<% category_level[nil].each do |root| %>
<%= render 'products/submenu/category_item', category: root %>
<% end %>
</ul>
哪个加载到:
<li class="list-one">
<a href="#"><%= category.name %><p><%= category.products.count %></p></a>
<% if category_level[category.id].present? %>
<ul class="list-style-upper-sub">
<% category_level[category.id].each do |child| %>
<%= render 'products/submenu/category_item', category: child %>
<% end %>
</ul>
<% end %>
</li>
它会显示,但是要花很长时间,因为它会打到“产品”表并遍历所有产品。因此,为了简化起见,我想我只需点击ProductCategory页面即可获得以下内容的计数:
def level_up
@category_counts = Connector::ProductCategory.group(:category_id).count
end
这实际上只会显示以下内容:
{54 => 11, 29 => 14, 51 => 19, 10 => 3202}
虽然是,但是10代表配件,我希望看到配件-3,202。
是否有任何建议清除名称属性?
答案 0 :(得分:1)
提供的模型如下所示:
class Category < ApplicationRecord
has_many :product_categories
has_many :products, through: :product_categories
end
class ProductCategory < ApplicationRecord
belongs_to :product
belongs_to :category
end
class Product < ApplicationRecord
has_many :product_categories
has_many :categories, through: :product_categories
end
可以通过联接并选择联接表的计数来获得相关项目的计数:
Category.left_outer_joins(:product_categories)
.select('categories.*, count(product_categories.*) AS product_count')
.group('categories.id')
.left_outer_joins
已在Rails 5中添加。对于早期版本,请使用:
.join('LEFT OUTER JOIN product_categories ON product_categories.category_id = category.id')
如果您不关心没有任何产品的类别,也可以使用.joins(:product_categories)
。
该计数将在每个记录上显示为.product_count
。
这也可以通过添加计数器缓存来实现:
class ProductCategory < ApplicationRecord
belongs_to :product
belongs_to :category, counter_cache: true
end
class AddProductCategoriesCountToCategories < ActiveRecord::Migration[5.2]
def change
add_column :categories, :product_categories_count, :integer, default: 0
end
end
这会将计数存储在categories.product_categories_count
中。当您的读取操作多于写入操作时,最好使用计数器缓存。