猫の魔法

主にruby系の技術メモを記載

has_many throughの苦悩

railsのhas_many throughの使い方が分からなかったという話。

モデルの関連付けでhas_manyは分かりやすい。1対多のモデルは1側にhas_manyをつければいい。

問題はhas_many throughでこれが良く分からない。多対多の時につけるというが多対多の場合、リレーション用のテーブルがあるとは限らない。必ずリレーション用のテーブルが必要なのか?引く側も引かれる側も両方につけるの?そもそも多対多のモデル自体を一対多にした方がいいのでは?学生の時にrailsを勉強した時は恥ずかしながらそこがまったく腑に落ちず理解が全然進まなかった。

月日は流れ、今になってもう一度railsを学んでみると、そもそもDBを主軸に考えるから良く分からなくなることに気がついた。今のrailsガイドは非常に分かりやすい。

Active Record の関連付け (アソシエーション) | Rails ガイド

このガイドを読んで分かったのはhas_many throughは多対多を表すというよりは、「このモデルとの関連付けはこのモデルを通して行うよ」という宣言という事だ。

なので、別にモデル関の関連が多対多でなくてもthroughを使うことで直接キーがないモデルを操作することが出来る。 よって「has_many throughを使う時は必ずリレーション用のテーブルが必要なのか?」という問はYesという事になる。

また以下のような正規化されていない多対多のモデルについてはhas_manyで結び付けられるような気がするのだが、そこら辺はネットで情報を見つける事ができなかった。 これについてはどっかで実験してみようと思う(そもそも正規化しろという話だが、既存システムの載せ替え等の場合、こう言うまずい作りが多々ある気がする)

f:id:nekomaho:20170314003934p:plain

モデル≠DBのテーブルで無い事にもっと早く気がつけば良かったという話でした。