前回はN+1問題が発生する状況とタイミングについて解説しました。
→【第1回】RailsのN+1問題と解決するためのメソッド完全版
もしまだご覧になっていなければ、一読していただけると理解がスムーズになります。
##本記事の内容
今回はN+1問題を解決するメソッドを5つ紹介していきます。
- joins
- left_outer_joins <=(本記事ではここまで)
- eager_load
- preload
- includes
##joinsメソッド
SQLのINNER JOIN句
が発行されます。(内部結合)
内部結合とは、指定したそれぞれのテーブルのカラムの値が一致するデータだけを取得する方法のことです。
内部結合についてはこちらを参考にすると理解しやすいです。
内部結合を行う(INNER JOIN句)
###使い方
モデル名.joins(:関連モデル)
軸となるモデルに対してjoinsメソッドを呼び出し、引数で関連モデルを指定します。
モデル名.joins(:関連モデル)
joinsメソッドは、関連モデルにあるカラムで絞り込みたい場合に使います。
User.joins(:post).where('post.title = ?','ruby')
例3では、UserモデルとPostモデルを結合したうえで、whereメソッド(WHERE句)を使いPostモデルのtitleカラムがrubyの投稿を取得しています。
このように、joinsメソッドは、関連モデルにあるカラムで絞り込みたい場合に使います。
##left_outer_joinsメソッド
SQLのLEFT_OUTER_JOIN句
が発行される。
参考:SQLではOUTER
を省略し、LEFT JOIN
と書くこともできる。
###使い方
モデル名.left_outer_joins(:関連モデル)
軸となるモデルに対してleft_outer_joinsメソッドを呼び出し、引数で関連モデルを指定します。
User.left_outer_joins(:post)
left_outer_joinsメソッドは、軸となるモデル(ここでいうところのUserモデル
)の全レコードと、関連モデル(Postモデル)の指定した条件にマッチするレコードを取得します。
下記の記事がわかりやすくまとめてあります。
参考:LEFT (OUTER) JOIN (左外部結合)を使ってデータを取得する
User.left_outer_joins(:post).where('post.title = ?','ruby')
joinsメソッド
との大きな違いは、軸となるモデルの全レコードを取得することです。
必要に応じて使い分けるのがよいでしょう。
##まとめ
-
joins
は、内部結合をおこない、指定したそれぞれのテーブルのカラムの値が一致するデータだけを取得する。 -
left_outer_joins
は、軸となるモデルの全レコードを取得し、関連テーブルの条件にマッチしたレコードを取得する。 -
joinsメソッド
とleft_outer_joins
の違いは、軸となるモデルの全レコードを取得すること。
5つのメソッドすべてを紹介しようと思いましたが、長くなりそうだったためここまでとします。
eager_load以降のメソッドは、joinsやleft_outer_joinsとはまた挙動が変わってくるので、ちょうどいいかなと思います。
それではまた次回、よろしくお願いします!