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

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


# 結合系メソッドの比較表
- joins
- eager_load
- preload
- includes

![Cursor_と_Rails結合まとめ_-_Google_スプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504414/f4b2ca75-678e-0a62-7113-449c329d52f4.png)

:::note info
補足: 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504414/2463ac18-0e02-3536-5bd4-ed09a59351f2.png)

戻り値サンプル
```ruby
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504414/e02922ce-ec73-ee9d-836c-80a0a5de2c78.png)

戻り値サンプル
```ruby
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504414/c5f06ffa-3821-3c2d-ddf0-ce0ff83511aa.png)

戻り値サンプル
```ruby
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'>
```