habtmとhas_many :through

多対多の関連を has_and_belongs_to_many で実装していると、関連テーブルをモデルとして扱えない。モデルとして扱うには、 has_many :through <関連テーブル> が使える。

habtm から has_many :through に変更すると、関連自体にメソッドを持たせるのが、うまくいかなくなるみたい。

  class Foo
  has_and_belongs_to_many :bar do
    def baz
      ...
    end
  end

みたいなやつ。

ひとつ不可解なことが起きたのは、この bar を削除した後でも、なぜか baz の呼び出しが成功して、不定の結果が得られてしまったとき。

  foo = Foo.find(id)
  foo.bars.baz ←コレ

なにが起きてるかというと、Bar クラスのクラスメソッドの baz が(たまたま同名だったので)呼ばれていたみたい。これはActiveRecordの機能なんだと思うけど、クエリ結果の配列に対してメソッドを呼んだとき、 NoMethodError になると、配列の中身に対してそのメソッドを呼び出してくれる(くれやがる!)。

なんでそんな仕様なのかは不明だけど、きっとなにか便利なことがあるんだろうな。知らないとハマる、というのはRoRの特徴のような気がしてきた。いや、なんでもそうなんだけど、特に「RoR脳」の要求度合いがけっこう高いなと思う。