🚀

【Rails】中間テーブルの関連付け(has_many)

2023/04/21に公開

ブックマーク機能

userモデルとboardモデルがあり、1対多の関係になっています。ブックマークできる機能を考えるとuserは複数のboardをブックマークでき、boardは複数のuserからブックマークされるので多対多の関係になる。このような時は間にbookmarkモデル(中間テーブル)を作り、userとbookmarkは1対多の関係で、boardとbookmarkは1対多の関係になるようする。

userとboardの1対多の関係を記述する。

model/user.rb
has_many :boards, dependent: :destroy
model/board.rb
belongs_to :user

userは複数のboardを持っているので複数形のboards、
boardは1人のuserしか持たないため単数形のuserとする。
こうするとuser.boardsでuserに紐づいたboardを取得することができる。

中間テーブルを用いた関連付けを記述する。

model/user.rb
has_many :boards, dependent: :destroy # この行はuserとboardの1対多の関係

has_many :bookmarks, dependent: :destroy
has_many :boards, through: :bookmarks
model/board.rb
belongs_to :user # この行はuserとboardの1対多の関係

has_many :bookmarks, dependent: :destroy
model/bookmark
belongs_to :user
belongs_to :board

よく見るとuser.boardsとすると1対多で記述したuserに紐づいたboardを取得する方法と、
bookmarkを経由してuserに紐づいたboardを取得する方法が同じコードになってしまっている、一応エラーにはならないが後に記述した方が優先されるらしいので前に記述した方は使えなくなってしまう。そんなときは

model/user.rb
has_many :boards, dependent: :destroy # この行はuserとboardの1対多の関係

has_many :bookmarks, dependent: :destroy
has_many :boards, through: :bookmarks # この行を削除
has_many :bookmark_boards, through: :bookmarks, source: :board # この行を追加

のようにする。こうするとuser.bookmark_boardsとするとbookmarkを経由してuserに紐づいたboardを取得することができる。source: :boardをつけることでuserがどのモデルに紐づいてるかを指定しているらしい。

Discussion