【Rails】belongs_toなActive Recordをwhere条件で利用する際の書き方

Ruby

belongs_toで紐づいているActive Recordの関連付けキーで検索をしたい場合は、当該カラムの値の代わりActive Recordモデルを検索条件に利用できます。1

たとえば以下のような1対多で紐づいたAuthorモデルとBookモデルのデータがあったとします。

mysql> select * from authors;
+----+--------+
| id | name   |
+----+--------+
|  1 | name_1 |
|  2 | name_2 |
+----+--------+

mysql> select * from books;
+----+---------+-----------+
| id | title   | author_id |
+----+---------+-----------+
|  1 | title_1 |         1 |
|  2 | title_2 |         2 |
+----+---------+-----------+

Bookモデルにおけるbelongs_toな関係がAuthorモデルです。関連付けキーはbooksテーブルのauthor_idになります。
このとき『author_idが1のレコードをbooksテーブルから検索する』という実装はいろいろな書き方ができます。

以下はすべて同じクエリが実行される等価なコードです。

### 検索対象: カラム, 検索条件: スカラ値
> Book.where(author_id: 1)

  Book Load (0.7ms)  SELECT `books`.* FROM `books` WHERE `books`.`author_id` = 1 LIMIT 11
=> #<ActiveRecord::Relation [#<Book id: 1, title: "title_1", author_id: 1>]>

### 検索対象: Active Record, 検索条件: Active Record
> author_1 = Author.find(1)
> Book.where(author: author_1)

  Book Load (0.7ms)  SELECT `books`.* FROM `books` WHERE `books`.`author_id` = 1 LIMIT 11
=> #<ActiveRecord::Relation [#<Book id: 1, title: "title_1", author_id: 1>]>

### 検索対象: カラム, 検索条件: Active Record
> author_1 = Author.find(1)
> Book.where(author_id: author_1)

  Book Load (0.7ms)  SELECT `books`.* FROM `books` WHERE `books`.`author_id` = 1 LIMIT 11
=> #<ActiveRecord::Relation [#<Book id: 1, title: "title_1", author_id: 1>]>

### 検索対象: Active Record, 検索条件: スカラ値
> Book.where(author: 1)

  Book Load (0.7ms)  SELECT `books`.* FROM `books` WHERE `books`.`author_id` = 1 LIMIT 11
=> #<ActiveRecord::Relation [#<Book id: 1, title: "title_1", author_id: 1>]>

同様に、複数検索(IN句)の場合もいろいろな書き方ができます。
以下は『author_idが1もしくは2のレコードをbooksテーブルから検索する』という実装の例です。

### 検索対象: カラム, 検索条件: スカラ値
> Book.where(author_id: [1, 2])

  Book Load (0.7ms)  SELECT `books`.* FROM `books` WHERE `books`.`author_id` IN (1, 2) LIMIT 11
=> #<ActiveRecord::Relation [#<Book id: 1, title: "title_1", author_id: 1>, #<Book id: 2, title: "title_2", author_id: 2>]>

### 検索対象: Active Record, 検索条件: Active Record
> author_1 = Author.find(1)
> author_2 = Author.find(2)
> Book.where(author: [author_1, author_2])

  Book Load (0.7ms)  SELECT `books`.* FROM `books` WHERE `books`.`author_id` IN (1, 2) LIMIT 11
=> #<ActiveRecord::Relation [#<Book id: 1, title: "title_1", author_id: 1>, #<Book id: 2, title: "title_2", author_id: 2>]>


### 検索対象: カラム, 検索条件: Active Record
> author_1 = Author.find(1)
> author_2 = Author.find(2)
> Book.where(author_id: [author_1, author_2])

  Book Load (0.7ms)  SELECT `books`.* FROM `books` WHERE `books`.`author_id` IN (1, 2) LIMIT 11
=> #<ActiveRecord::Relation [#<Book id: 1, title: "title_1", author_id: 1>, #<Book id: 2, title: "title_2", author_id: 2>]>

### 検索対象: Active Record, 検索条件: スカラ値
> Book.where(author: [1, 2])

  Book Load (0.7ms)  SELECT `books`.* FROM `books` WHERE `books`.`author_id` IN (1, 2) LIMIT 11
=> #<ActiveRecord::Relation [#<Book id: 1, title: "title_1", author_id: 1>, #<Book id: 2, title: "title_2", author_id: 2>]>