多対多
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メソッドで指定された値と同じである必要がある。
参考記事