2011-04-18

has_and_belongs_to_manyのときのvalidate

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Railsで多対多の関係を
has_and_belongs_to_many
で表現したときのお話です。

Group

Member
があったとして
Memberは複数のGroupに参加可能とします。
なので
has_and_belongs_to_many
で関係を定義しておきます。

しかし特別ななんらかの理由でGroupに参加できない場合があるとします。
モデルで制約を作るならばGroupモデルとかに以下のようなvalidateを用意すれば
よいと思ったわけです。
def validate
  if xxx == yyy
    errors.add(:memgers,"都合によりこのグループはダメです")
  end
end

確かにvalidateはかかるのですが、
どういうわけか登録は出来てしまう感じでした。

でこれをなんとかしたいなぁと思ったら
has_and_belongs_to_many_with_deferred_save
というものが見つけました。
https://github.com/TylerRick/has_and_belongs_to_many_with_deferred_save

これを使えば使えるようになりました。

インストールは以下のような感じで。
./script/plugin install git://github.com/TylerRick/has_and_belongs_to_many_with_deferred_save.git

そしてGroupモデルは以下のような感じです。

has_and_belongs_to_many_with_deferred_save :members ,:before_add => :check_member

def validate
  self.members.each do |m|
    if m.xxx == yyy
      errors.add(:memgers,"都合によりこのグループはダメです")
    end
  end
end

def check_item(members)
  members.each do |m|
    if m.xxx == yyy
      raise("都合によりこのグループはダメです")
    end
  end
end

validateはなくてもよいとは思うのですが、ActiveScaffoldでvalidateのメッセージを拾うためには必要だったので他にもあるとよいかもしれないです。

なんかいろいろと制約がhas_and_belongs_to_many_with_deferred_saveにはありそうな気配ですが、とりあえずよしとしてみます。
コメントを投稿