アソシエーション
テーブル間のリレーションシップをモデルの上の関係として操作できるようにする仕組み。
アソシエーションを利用すると複数のテーブルにまたがるデータ操作もより直感的に利用できる。
参照先テーブルと参照元テーブル
【例:Twitter】
1つユーザ(usersテーブル
)に対して、複数のツイート(tweetsテーブル
)が結びついているとする。
users | tweets | |
---|---|---|
id | id | |
name | user_id(FK) | |
context | ||
password | created_at | |
created_at | updated_at | |
updated_at |
- 参照先テーブル(被参照テーブル)
関連において主キーを持つテーブル
usersテーブル
に当たる
- 参照元テーブル
外部キーを持つテーブル
tweetsテーブル
に当たる
※ 主キー
:関係データベースにおける行(レコード)を一意に識別するための列(カラム)(usersテーブルのid)
※ 外部キー
:他のテーブルとの関連づけに使うキー(tweetsテーブルでusersテーブルに関連づけされたカラム。要はtweetsテーブルのuser_id)
belongs_to
参照元テーブルから参照先テーブルの情報にアクセスするアソシエーション
参照元テーブル → 参照先テーブル
class Tweet < ApplicationRecord
belongs_to :user
end
belongs_to
によって参照先(userモデル)から値を参照できる。
@tweet.user.name
has_many
1:nの関連を表すアソシエーション
belongs_to
では参照元テーブル → 参照先テーブルへのアクセス
has_many
を利用することでようやく双方向の関係を定義可能に
class User < ApplicationRecord
has_many :tweets
end
このようにtweets
と 複数形 になっていることから1つのUserオブジェクトに対して複数のTweetオブジェクトが存在するという意味になる。
@user.tweets.each do |tweet|
p tweet.context
end
tweetsメソッドの戻り値が配列であることに注意
has_one
1:1の関係
class User < ApplicationRecord
has_one :author
end
class Author < ApplicationRecord
belongs_to :user
end
@user.author.name
has_many through
n:mの関係を表現するアソシエーション。
items | reviews | users |
---|---|---|
id | id | id |
name | item_id(FK) | |
price | user_id(FK) | password |
description | context | created_at |
created_at | created_at | updated_at |
updated_at | updated_at |
item:review = 1:n
item:user = n:m
user:review = 1:n
class Item < ApplicationRecord
has_many :reviews
has_many :users through: :reviews
end
class Review < ApplicationRecord
belongs_to :item
belongs_to :user
end
class User << ApplicationRecord
has_many :reviews
has_many :items through: :reviews
end
Item → Review → Userによる回りくどいアクセスをしなくても
has_many thorough
を利用することでItemから直接Userモデルにアクセスすることができる。