何番煎じ?って感じですが、自分が知りたい情報を自分が見やすい形でまとめました。
結合系メソッドの比較表
- joins
- eager_load
- preload
- includes
補足: includesの「参照があればeager、なければpreload」というのは、関連テーブルを参照しているかどうかで、自動で使い分けてくれるということです。
User.includes(:books)
の場合はpreloadが使われます。
User.includes(:books).where(title: { "Ruby" })
場合はeager_loadを使われます。
ActiveRecordのクエリインターフェースと、発行されるSQLの対応表
今回使用したテーブル定義(簡易)
Userテーブル
- name
- age
Bookテーブル
- user_id
- title
- memo
Userが親、Bookが子
- User has_many Books
- Book belongs_to User
joins
戻り値サンプル
User.joins(:books)
=>
[#<User:0x000000010a074d00 id: 1, name: "user01", created_at: Fri, 12 May 2023 15:28:43.188967000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:06.987113000 UTC +00:00, age: 20>,
#<User:0x000000010a074c60 id: 1, name: "user01", created_at: Fri, 12 May 2023 15:28:43.188967000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:06.987113000 UTC +00:00, age: 20>,
#<User:0x000000010a074bc0 id: 2, name: "user02", created_at: Fri, 12 May 2023 15:28:49.759047000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:02.135818000 UTC +00:00, age: 20>]
User.joins(:books).where(books: { title: "Ruby" })
=>
[#<User:0x0000000107f5c190 id: 1, name: "user01", created_at: Fri, 12 May 2023 15:28:43.188967000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:06.987113000 UTC +00:00, age: 20>,
#<User:0x00000001075f2960 id: 1, name: "user01", created_at: Fri, 12 May 2023 15:28:43.188967000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:06.987113000 UTC +00:00, age: 20>,
#<User:0x00000001075f28c0 id: 2, name: "user02", created_at: Fri, 12 May 2023 15:28:49.759047000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:02.135818000 UTC +00:00, age: 20>]
eager_load
戻り値サンプル
User.eager_load(:books)
=>
[#<User:0x0000000108c38c38 id: 1, name: "user01", created_at: Fri, 12 May 2023 15:28:43.188967000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:06.987113000 UTC +00:00, age: 20>,
#<User:0x000000010961f5a8 id: 2, name: "user02", created_at: Fri, 12 May 2023 15:28:49.759047000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:02.135818000 UTC +00:00, age: 20>,
#<User:0x000000010961f328 id: 3, name: "user03", created_at: Fri, 12 May 2023 15:43:17.323247000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:17.323247000 UTC +00:00, age: 30>]
User.eager_load(:books).where(books: { title: "Ruby" })
=>
[#<User:0x00000001076a8530 id: 1, name: "user01", created_at: Fri, 12 May 2023 15:28:43.188967000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:06.987113000 UTC +00:00, age: 20>,
#<User:0x000000010768db68 id: 2, name: "user02", created_at: Fri, 12 May 2023 15:28:49.759047000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:02.135818000 UTC +00:00, age: 20>]
preload
戻り値サンプル
User.preload(:books)
=>
[#<User:0x00000001082164a8 id: 1, name: "user01", created_at: Fri, 12 May 2023 15:28:43.188967000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:06.987113000 UTC +00:00, age: 20>,
#<User:0x0000000108216408 id: 2, name: "user02", created_at: Fri, 12 May 2023 15:28:49.759047000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:02.135818000 UTC +00:00, age: 20>,
#<User:0x0000000108216368 id: 3, name: "user03", created_at: Fri, 12 May 2023 15:43:17.323247000 UTC +00:00, updated_at: Fri, 12 May 2023 15:43:17.323247000 UTC +00:00, age: 30>]
User.preload(:books).where(books: { title: "Ruby" })
=>
<ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'books.title' in 'where clause'>