Railsを学んでいると必ずでてくるjoinsとwhere。
なんとなく使っているけど、いまいち理解できていない。
そんな自分に向けて、今回はjoinsとwhereの基礎をアウトプットしたいと思います。
SQLの基本構造
SQLの基本構造をおさらいします。
SELECT # ほしいカラム
FROM # どのテーブルから
JOIN # 他のテーブルと結びつける
WHERE # 条件で絞り込むRailsのjoinsとwhereはこのSQLを自動生成しています。
joinsメソッドとは?
joinsは テーブルとテーブルを結合するためのメソッドです。
Railsのjoinsは、SQLのINNER JOIN(内部結合)を発行します。
INNER JOINとは、お互いに関連するデータだけを結びつけて、ひとつの大きな「横長の表」として扱えるようにする仕組みのこと。
Railsでは複数のテーブルに情報を分けて保存するため、記事(posts)とタグ(tags)のように別のテーブルにある情報をまとめて扱いたいときにJOINが必要となります。
joins を理解するための前提(Post・Tag・PostTagの関係)
よくある記事とタグの関係を例にjoinsを解説します。
posts テーブル(記事):
| id | title |
|---|---|
| 1 | Rubyを学ぶ |
| 2 | Rails入門 |
→ 記事そのものを保存するテーブル
tags テーブル(タグ):
| id | name |
|---|---|
| 1 | Ruby |
| 2 | Rails |
→ タグ(ラベル)を保存するテーブル
post_tags テーブル(中間テーブル):
| post_id | tag_id |
|---|---|
| 1 | 1 |
| 2 | 2 |
→ 「どの記事にどのタグがついているか」を管理する中間テーブル
つまり関係はこうです:
Post(記事)──< PostTag >── Tag(タグ)このように、記事とタグは直接つながっておらず、中間テーブルを経由して結びついています。
だからこそ、複数テーブルを横に結合(JOIN)しないと、「どの記事にRubyタグがついているのか?」 という検索ができません。
例:PostとTagを結合する
PostとTagを結合するとき、次の1行でJOINできます。
Post.joins(:tags)「Postモデルと関連づけられているTagテーブルを結合して検索できる状態にする」という意味です、。
Rails が内部で発行する SQL(イメージ)
内部では次のようになっています。
SELECT posts.* FROM posts
INNER JOIN post_tags ON post_tags.post_id = posts.id
INNER JOIN tags ON tags.id = post_tags.tag_id;- INNER JOIN は「関連するデータが存在するものだけ結びつける」
- 3つのテーブルが横長につながって1つの大きな表になる
whereメソッドとは?
where は 検索条件を指定してデータを絞り込むためのメソッド です。
joins が「テーブル同士をつなげる」役割だったのに対し、where は「条件でフィルターをかける」役割を持っています。
基本のwhere
Post.where(published: true)これは、「published カラムが true の記事だけ取り出したい」という意味。
Rails が内部で発行する SQL はこうなります:
SELECT "posts".* FROM "posts" WHERE "posts"."published" = TRUE;joins と組み合わせると「関連テーブルの条件」で検索できる
joins の説明で出てきた例を思い出してください。
- Post(記事)
- Tag(タグ)
- PostTag(中間テーブル)
この3つを JOIN しただけでは、まだ絞り込みは行われません。
そこで where を組み合わせます。
Post.joins(:tags).where(tags: { name: "Ruby" })
# tags テーブルの name カラムが "Ruby" のデータだけを取り出したいJOIN があるからこそ、別のテーブルのカラム(tags.name)で絞り込めるのです。
このコードが発行するSQL
SELECT posts.* FROM posts
INNER JOIN post_tags ON post_tags.post_id = posts.id
INNER JOIN tags ON tags.id = post_tags.tag_id
WHERE tags.name = 'Ruby';これを見ると where が果たしている役割が明確です。
- joins→ テーブルを横につなげて検索できる状態を作る
- where → その中から「Rubyタグの記事だけ」を抽出する
まとめ
- joins はテーブルを「結合」するメソッド
→ 複数テーブルを横方向につなげて検索できる状態を作る - where は「条件で絞り込む」メソッド
→ JOIN したテーブルのカラムも条件に使える - Rails はこの2つを組み合わせることで
「Post.joins(:tags).where(tags: { name: 'Ruby' })」のような多テーブル検索が簡単に書ける
JOIN と WHERE の理解は、Railsにおけるデータ検索の大きな基礎。
この記事が、検索処理の「なぜこう書くのか?」を理解するきっかけになれば幸いです。