見出し画像

N+1問題を回避するrenderの書き方【Day 6/30 2nd】

【注意】本記事でN+1問題は解決しません。ただのrenderの書き方でした。自戒のために残しておきます。ただしくはこちらへ。


こんにちは、たわらです。

本記事はN+1問題と、問題を回避するrenderの書き方を整理した記事です。

N+1問題は、必要以上にSQLを発行しまうこと

SQLを発行する、ということは、データベースからデータを抽出する操作のことです。この作業が増えると、ウェブアプリケーションのパフォーマンスが落ちてしまい、ユーザーの満足度の低下につながってしまいます。

なので、SQLを発行する回数を減らしたほうがよいのですね。

具体的には、例えば次のようなコードがあります。

app/controllers/user_controller.rb

def
  @user = User.all
end
app/views/index.html.erb

<ul class="users">
 <% @users.each do |user| %>
   <li>
     <%= gravatar_for user, size: 50 %>
     <%= link_to user.name, user %>
   </li>
 <% end %>
</ul>

上記の書き方だと、、、

Userデータベースからユーザー一覧情報を取得して@userに格納し、さらに、eachメソッドのブロックの中で、Userの数だけ、userの情報を取得して表示しています。

ここでは、「Userデータベースからユーザー一覧情報」を1回情報を取得し、「eachメソッドのブロックの中で、Userの数だけ」(n回)情報を取得していることになります。

これがN+1問題です。

なので、SQLを発行する回数を減らす方針を取ります。

まずブロックのなかの二行を、「_user.html.rb」という部分パーシャルを作成します。

そして、こんなふうに書き換えます。

app/views/index.html.erb

<ul class="users">
 <%= render @users %>
</ul>

Railsは、@usersという変数から自動的に「_user.html.rb」を探してくれます。

@usersに直接renderメソッドを使用することで、「_user.html.rb」をuserの数だけ繰り返し表示してくれます。

この場合のSQLの発行は、コントローラーで@usersを取得するときの一回だけ(のはず)です。

他に対策として、preloadメソッドやeager_loadメソッドなのだがあるみたいですが、ここでは紹介しません。

読んでくださったくださった、ありがとうございます。


この記事が気に入ったらサポートをしてみませんか?