多対多
class Post < ApplicationRecord
has_many :tags, class_name: 'Tagging'
has_many :programming_languages, through: :tags
end
class Tagging < ApplicationRecord
belongs_to :post
belongs_to :programming_language
end
class ProgrammingLanguage < ApplicationRecord
has_many :tags, class_name: "Tagging"
has_many :posts, through: :tags
end
#has_many
第1引数
has_many
の第一引数に渡したシンボルがそのままメソッド名になる。
この例では、PostがもつTaggingをpost.tags
で取得できるようになる。
この時、どのクラス名を参照すれば良いのか、それすなわちどのテーブルを参照すればいいのかわからない状態なので class_name
オプションにクラス名(モデル名)を指定してあげる。
through option
through
オプションは中間テーブルの値を取得する際の関連名(すなわちメソッド名)を指定する。この例でいうとTaggingテーブルが中間テーブルの役割であり、Post
からのTagging
への関連名はtags
に指定しているのでこれをthrough
へ渡す。
source option
この例ではないがこのオプションも使う場面も出てくることがよくあるので記載する。
先ほどのthrough
オプションは、Post
からTagging
への関連名を指定した。
では、Tagging
からProgrammingLanguage
への関連はどうなっているのかというと、has_many
の第1引数の値となる。つまり、has_manyが以下のようであるとき、
has_many :hoge, through: :tags
tag.hoge
によってProgrammingLanguage
のレコードをとってくるのである。
よって、この:hoge
の値はTagging
のbelongs_to
メソッドで指定された値と同じである必要がある。
参考記事