我面临着n+1的问题时,使用条件的数组,来自包括查询。
下面是以下表格:
rems
|id| |name|
1 aaa
2 bbb
rem_correlatives
|id| |rem_id| |name| |deleted| |pending_tr|
1 1 qqqq1 0 0
2 1 qqqq2 0 1
3 1 qqqq1 1 0
4 1 qqqq2 1 1
5 1 qqqq1 0 0
6 1 qqqq2 0 1
7 1 qqqq1 1 0
8 1 qqqq2 1 1
9 2 qqqq1 0 0
10 2 qqqq2 0 1
11 2 qqqq1 1 0
12 2 qqqq2 1 1
13 2 qqqq1 0 0
14 2 qqqq2 0 1
15 2 qqqq1 1 0
16 2 qqqq2 1 1
字符串
以下是模型:
class Rem < ApplicationRecord
has_many :rem_correlatives
end
class RemCorrelative < ApplicationRecord
belongs_to :rem
end
型
下面是位于/app/controllers/rems_controller.rb的名为rems_controller. rb的控制器
def index
@list_array = Rem.includes(:rem_correlatives).all
end
型
下面是位于/app/views/rems/index.html.erb的索引视图
<% @list_array.each do |array| %>
<% array.name %>
<% @check_result = array.rem_correlatives.where("deleted=0 AND pending_tr= 1)%>
<% if @check_result.present? %>
No
<% else %>
Yes
<% end %>
<% end %>
<% end%>
型
x1c 0d1x的数据
我尝试了这个变通代码,它使用列pending_tr=1和deleted=0显示数据数组,但似乎不是一个好的做法。
<% @list_array.each do |array| %>
<% array.name %>
<% array.rem_correlatives.each do |rem_correlative|%>
<!-- Create condition pending_tr=1 AND deleted=0 -->
<% if rem_correlative.pending_tr == 1 && rem_correlative.deleted == 0%>
<% @check_condition = "No" %>
<% else %>
<% @check_condition = "Yes"%>
<% end %>
<% end %>
<!-- Check results from array if the word yes exists -->
<% if @check_condition.include?("Yes") %>
si
<% else %>
no
<% end %>
<% end%>
型
下面是使用解决方案代码时的后端结果,它的工作和不显示n+1问题。
的
我如何防止n+1问题从数组生成额外的条件作为良好的代码?
2条答案
按热度按时间noj0wjuj1#
我将在模型中创建一个具有作用域的专用关联。
字符串
然后在控制器和视图中使用这个关联。
型
lbsnaicq2#
目前,在您的控制器中,您使用
Rem.includes(:rem_correlatives).all
来加载Rem记录及其关联的rem_correlatives
。但是,当您稍后重新启动@list_array
并访问array.rem_correlatives
时,它仍然会为每条Rem记录生成额外的查询,从而导致N+1查询问题。要解决这个问题,您可以使用includes方法预加载必要的关联,并利用查询条件来过滤关联的记录。以下是如何修改控制器代码:
字符串
在您看来,通过此更改,您可以忽略@list_array,而不会对每个Rem记录造成额外的查询:
型