前回までの記事
はじめに
前回の記事で、Railsで多対多の関係を持つモデルの設定と基本的なデータ取得方法について説明しました。今回は、includes
と joins
の違いに焦点を当て、これらのメソッドをいつ、どのように使い分けるべきかを詳しく見ていきます。
joins
メソッドの基本
joins
はSQLの INNER JOIN
を使ってテーブルを結合し、関連するデータを取得するために使用します。しかし、joins
だけでは関連テーブルのカラムは自動的には選択されません。これが意味するのは、関連データにアクセスしようとした場合、追加のクエリが必要になることです。
@services = Service.joins(:categories)
このクエリは services
と categories
を結合しますが、Service
オブジェクト内で直接 Category
のデータにアクセスすることはできません(追加のクエリを記述しないと、@servicesに空の配列が代入されます)。これが、直感に反しているように感じるかもしれません。
補足: @services = Service.joins(:category)と記述した場合
以下のようなエラーが出る。
ActiveRecord::ConfigurationError at /services
Can't join 'Service' to association named 'category'; perhaps you misspelled it?
includes
メソッドの利用
一方、includes
は関連データを事前に読み込むために使用されます(Eager Loading)。これにより、必要なすべての関連データが初期のクエリで読み込まれるため、後からアクセスする際に追加のクエリが発生しません。これは特に、ビューで多くの関連データに頻繁にアクセスする場合に有効です。
@services = Service.includes(:categories).all
この方法では、各 service
から service.categories
にアクセスする際に、関連する categories
がすでにロードされているため、効率的です。
joins
と includes
の使い分け
-
joins
の利用: 特定の条件でフィルタされたレコードを抽出する場合や、関連テーブルのデータでソートする場合に有効です。例えば、特定のカテゴリに属するサービスだけをリストアップする場合などです。 -
includes
の利用: データを表示する際に関連データも一緒に扱う必要がある場合、または N+1 クエリ問題を回避したい場合に適しています。
まとめ
includes
と joins
の違いを理解することは、Railsで効率的なデータ取得戦略を立てる上で非常に重要です。各メソッドの使用目的を理解し、適切な状況で適切なメソッドを選択することで、アプリケーションのパフォーマンスと保守性を向上させることができます。
次回以降の記事