追加の条件を生成する配列からの n+1 の問題を防ぐにはどうすればよいですか?
概要
include クエリからの配列の条件を使用すると、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%>
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 の問題を防ぐにはどうすればよいですか?
解決策
モデル内のスコープとの専用の関連付けを作成します。
# in app/models/rem.rb
has_many :pending_rem_correlatives,
class_name: 'RemCorrelative', -> { where(deleted: false, pending_tr: true) }
そして、この関連付けをコントローラーとビューで使用します。
# in the controller
@rems = Rem.includes(:pending_rem_correlatives).all
# in the view
<% @rems.each do |rem| %>
<%= rem.name %>
<% if rem.pending_rem_correlatives.any? %>
No such rem correlatives
<% else %>
There are matching rem correlatives
<% end %>
<% end %>