LoginSignup
3
1

Railsの結合系メソッドの使い分けまとめ( joins / eager_load / preload / includes )

Last updated at Posted at 2023-05-30

何番煎じ?って感じですが、自分が知りたい情報を自分が見やすい形でまとめました。

結合系メソッドの比較表

  • joins
  • eager_load
  • preload
  • includes

Cursor_と_Rails結合まとめ_-_Google_スプレッドシート.png

補足: 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

Cursor_と_Rails結合まとめ_-_Google_スプレッドシート.png

戻り値サンプル

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

Cursor_と_Rails結合まとめ_-_Google_スプレッドシート.png

戻り値サンプル

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

Cursor_と_Rails結合まとめ_-_Google_スプレッドシート.png

戻り値サンプル

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'>
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1