【Rails】1個むこう側にあるテーブルの情報を取るSQL文でやる方法

2018年4月9日

SQLやRailsプログラミングの知識が浅いのでなんと表現したらよいかわからない。
だから検索の仕方もわからない。

それでこのようなタイトルになった。

→1個むこう側にあるテーブルの情報を取るSQL文とRailsでやる方法

例えばショップの口コミサイトを作っていて、以下のようなデータベース図になっています。

これでショップの詳細画面にユーザーのニックネーム(nickname)や、口コミ(comment)を一覧表示させたいと思っています。

この時、ショップから見ると上記のユーザー情報はKuchikomisテーブルを挟んで向こう側にありますから、簡単にはユーザー情報が取れません。

で、これを取る方法を探していました。

遠くにあるテーブルを取るSQL文は結合を使うようだ

SQL文の書き方は調べまくってヒントをさらに深掘りしていったらわかりました。

例えばショップIDが2番の口コミを取ってきて、その口コミを投稿したユーザー情報(ID、ニックネーム、コメント)を取ってきたい。

このような場合は以下の文です。

mysql> SELECT users.id, users.nickname,kuchikomis.comment FROM kuchikomis JOIN users ON kuchikomis.user_id = users.id WHERE kuchikomis.shop_id = 2;

これでとれました。

+—-+—————–+———————————————————————+
| id | nickname | comment |
+—-+—————–+———————————————————————+
| 3 | 山さん | 日高屋新宿店は安くて美味しくて駅チカでいい感じ。 |
+—-+—————–+———————————————————————+

JOINを使ってkuchikomisテーブルとusersテーブルを結合しています。結合条件は ON kuchikomis.user_id = user.idなわけです。

つまりkuchikomiテーブルのuser_id が、userテーブルのidと一致するような結合条件を指定しています。

これで出来ました。

Railsプログラミングで遠くのテーブルを取るには

で、Railsでやるにはどうすればよいか‥という話まで進みました。

Kuchikomiのモデルに以下のようにbelongs_to を記述します。

class Kuchikomi < ApplicationRecord
  belongs_to :shop
  belongs_to :user

こうすることでコントローラー側で

kuchikomi.user

とやればユーザーのインスタンスがとれるようになります。

kuchi = Shop.find(2).kuchikomis
これでショップID2番に投稿された全ての口コミ達(具体的にはインスタンスを配列に入れたもの‥かな)が取れます。さらに

kuchi = Shop.find(2).kuchikomis.order(‘created_at DESC’)
これで最新の口コミ順からとります。

user0 = kuchi[0].user
user1 = kuchi[1].user

こんなふうにして、それぞれのユーザーのインスタンスがとることができました。