N+1 問題

[N+1 問題]とは?
必要以上にSQLが実行されてしまい、パフォーマンスが落ちること。
ex)掲示板の一覧画面に個別の掲示板を全て表示する場合(以下コードを参照) 個別の掲示板を取得するのにSQL1回実行 取得した個別の掲示板からユーザー情報を個別の掲示板の数だけN回取得するのにSQLN回実行する(取得した個別の掲示板モデルとユーザーモデルはアソシエーション関係にあり、個別の掲示板モデルに外部キーでuser_idがある)

[app/controller/board_controller.rb]

def index
  @boards = Board.all
end
[app/views/index.html.erb]

<% @boards.each do |board| %>
  <%= render partial: "board", locals: { board: board } %>
<% end %>

[N+1 問題の解消法]

controllerで全掲示板を取得する際に、includesメソッドを利用する。 includesメソッドは、アソシエーションの関連付けを事前に取得してN +1問題を解決するメソッドです。 [includesメソッドの使い方] モデル名.includes(:関連名)
※注意
関連名は、テーブル名の事ではない。

ex)

def index
    @boards = Board.all.includes(:user).order(created_at: :desc)
  end

個別掲示板を掲示板一覧画面でeach文で回さないようにする。

[views ファイル]

<%= render partial: 'board', collection: @boards %>

上記のコマンドは、以下の条件を満たすと[views ファイル1]のように省略できる。 ・呼び出す部分テンプレートがviewsフォルダ内にあるboardsフォルダに存在する ・部分テンプレート名が_comment.html.erbである ・部分テンプレート内で使う変数がboardである

[views ファイル1]

<%= render @boards %>

上記のように、コントローラーに記載した全掲示板を取得する変数をrenderにそのまま渡すと、同じディレクト下の@変数単数形の部分テンプレートが参照される。 @変数はeachされて部分テンプレート名に入る。 ex) [_board.html.erb]を[boardsディレクトリ]下に持ってきて掲示板の一覧を表示することができる。

参考記事:

【Rails】N+1問題って何?原因と対処法を徹底解説! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト

まるで魔法だな(パーシャルをrenderし繰り返し処理をする) - Qiita

render先に変数が上手く渡らないときに確認すること - Qiita

【Rails基礎】ややこしい部分テンプレートの省略形について簡単にまとめてみた|TechTechMedia

【Rails】部分テンプレートの使い方を徹底解説! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト

【Rails基礎】ややこしい部分テンプレートの省略形について簡単にまとめてみた|TechTechMedia