モデル間の1対多、多対多のなどの関連付けの事をアソシエーションという
アソシエーションについては現実世界に置き換えるとわかりやすい。
今回はメッセージ投稿アプリを例にしている。
「一人のユーザーは何個もメッセージを投稿できる」= 1対多 というように現実的に考えると、
どのような関連付けが行えるかが見えてくる。
1対多の関連付け(アソシエーション)
メッセージ投稿機能をもったアプリの場合は次のようになる。
- Userテーブル
| id | 備考 | |
|---|---|---|
| 1 | arai@example.com | 新井さん |
| 2 | saitou@example.com | 斎藤さん |
| 3 | suzuki@example.com | 鈴木さん |
- Postテーブル
| id | content | user_id | 備考 |
|---|---|---|---|
| 1 | ありがとう | 2 | 斎藤さんのメッセージ |
| 2 | 最高! | 1 | 新井さんのメッセージ |
| 3 | よろしく | 3 | 鈴木さんのメッセージ |
| 4 | おはよう | 1 | 新井さんのメッセージ |
| 5 | おやすみ | 2 | 斎藤さんのメッセージ |
というように「ありがとう」「おやすみ」というメッセージを投稿したのは「斎藤さん」だという事がわかります。
idのようなカラムを「主キー(PK)」。user_idのようなカラムを「外部キー(FK)」と呼ぶ。
belongs_to
belogs_toの関連付けを行うと、モデル間に1対1の関連性が設定される。
上記のアプリの場合で言うと、1つのメッセージは1人の人間と繋がっているので、Postテーブルにbelongs_toを入れる事になる。
class Post < ApplicationRecord
belongs_to :user
end
belongs_toで関連付けするモデル名は必ず「単数形」にする事。
関連付けのマイグレーションはこんな感じ。
class CreatePosts < ActiveRecord::Migration[6.0]
def change
create_table :posts do |t|
t.string :content
t.references :user
t.timestamps
end
end
end
t.references :userの別の書き方としてt.bigint :小文字モデル名_idと書くと外部キー(FK)として示す事ができるが、現在のRailsのバージョンでは、上記の書き方の方が良いみたい。
has_many
has_manyの関連付けは他とのモデルに「1対多」の関連性がある事を表す。
先ほどのメッセージ投稿アプリで言うと、
class User < ApplicationRecord
has_many :posts
end
という形で表現できる。「1人のユーザはたくさんのメッセージを投稿できる」って事。
反対側のモデルには belongs_toが使われる事が多い。
この関連付けに対応するマイグレーションはこんな感じ。
class CreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users do |t|
t.string :email
t.timestamps
end
create_table :posts do |t|
t.belongs_to :user
t.string :content
t.timestamps
end
end
end
まとめ
今回はActive Recordの関連付け(アソシエーション)について、自分の頭の中の整理という感じでまとめてみました。
理解が間違っている点などありましたら、教えていただけると幸いです。