ActiveRecordではどのようにテーブルの結合を記述したらいいのか。
joinsで複数テーブルの結合
SQLクエリ
「JOIN〜ON〜」を繰り返すことで、3つ以上のテーブルを結合することもできる。
一度に3つのテーブルが結合されるわけではなく、前から順に1つずつ結合処理が行われる。
例)家計簿テーブル、費目テーブル、経費区分テーブルの結合(家計簿テーブルの日付カラム・費目テーブルの名前カラム・経費区分テーブルの名称カラムを結合する)
スッキリわかるSQL参考書例
SELECT 日付, 費目.名前 AS 費目名, 経費区分.名称 AS 経費区分名 (取得したい列の名前)
FROM 家計簿 (家計簿テーブルに対して)
JOIN 費目 (まず費目テーブルを結合)
ON 家計簿.費目.id = 費目.id (結合条件)
JOIN 経費区分 (その結果にさらに経費区分を結合)
ON 費目.経費区分id = 経費区分.id (結合条件)
ActiveRecordクエリ
関連付けを行なった上で以下のように記述すると上記と同じように指定したカラムを取得できる
class 家計簿 < ApplicationRecord
scope :joined_data, -> {
joins(:費目, :経費区分)
.select('家計簿.日付, 費目.名前 AS 費目名, 経費区分.名称 AS 経費区分名')
}
end
例1(複数の関連付け)
「カテゴリーが1つあり、かつコメントが1つ以上ある、すべての投稿を返す」場合
SQLクエリ
SELECT posts.* FROM posts
INNER JOIN categories ON articles.category_id = categories.id
INNER JOIN comments ON comments.article_id = articles.id
ActiveRecordクエリ
Posts.joins(:category, :comments)
例2(ネストした関連付け)
「ゲストによるコメントが1つある投稿をすべて返す」場合
SELECT posts.* FROM posts
INNER JOIN comments ON comments.post_id = posts.id
INNER JOIN guests ON guests.comment_id = comments.id
Post.joins(comments: :guest)
参考
すっきりわかるSQL入門 第2版
Railsガイド