我正在使用项目符号 gem 来找出我的应用程序有哪些 n+1 查询问题,结果发现我有 3 个问题:
user: Rashed N+1 Query detected Sale => [:shop] Add to your finder: :includes => [:shop] user: Rashed N+1 Query detected Shop => [:malls] Add to your finder: :includes => [:malls] user: Rashed N+1 Query detected Shop => [:categories] Add to your finder: :includes => [:categories]
问题是我不太确定如何使用包含来解决问题,因为我的模型是如何相互关联的。我有 4 个模型:Sale、Shop、Mall 和 Category。这些是我的模型的关联:
class Shop < ActiveRecord::Base
has_many :categorizations
has_many :categories, :through => :categorizations
has_many :mall_shops
has_many :malls, :through => :mall_shops
has_many :sales, dependent: :destroy
end
class Sale < ActiveRecord::Base
belongs_to :shop
end
class Mall < ActiveRecord::Base
has_many :mall_shops
has_many :shops, :through => :mall_shops
has_many :sales, :through => :shops
end
class Category < ActiveRecord::Base
has_many :categorizations
has_many :shops, :through => :categorizations
has_many :sales, :through => :shops
end
在我的销售索引页中,显示了所有的销售记录,每条销售记录都属于一个商店,每个商店有很多类别和很多商城。对于显示的每条销售记录,都会迭代该销售商店所属的所有商场和类别(用于过滤目的)。这是我的销售索引页面中的相关代码:
<% @sales.each do |sale| %>
<div class="<% sale.shop.malls.each do |m| %> mall<%= m.id %><% end %><% sale.shop.categories.each do |c| %> category<%= c.id %><% end %>">
.
.
end
还有我的销售 Controller :
class SalesController < ApplicationController
def index
@malls = Mall.all.order('name ASC')
@categories = Category.all.order('category_type ASC')
@shops = Shop.all
@sales = Sale.where('offer_end >= ?', Date.today).order('offer_end ASC')
end
end
那么解决我遇到的 n+1 查询问题的最佳方法是什么?为了更好地了解我的应用程序,这是我正在构建的网站:www.shopwatchkw.com
最佳答案
在 Controller 中,尝试以下操作:
@sales = Sale.includes(shop: [:categories, :malls])
.where('offer_end >= ?', Date.today)
.order('offer_end ASC')
基本上,您从顶级模型开始,并通过 includes
语句预先加载其子模型。 Bullet 告诉您添加 .includes(:shop)
,然后,它可能会告诉您有关 :categories
和 :mails< 的相同信息
,正如您所描述的,它们是 Shop 上的子查询。
关于ruby-on-rails - 如何解决包含的 n+1 查询问题 - Rails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37774153/