複合フォーム(aaa http://railsforum.com/viewtopic.php?id=28447)で複数の子モデルを使用しています。フォームはうまくいきますが、の子モデルのセットのプロパティを検証してから、フォームデータをデータベースに受け入れる必要があります。私は、これを行うための主に働く、非常にクルージングな方法を考え出した。よりよい方法が必要なように思われるので、私は提案を求めています...複数の子モデルを複合フォームで検証するレール
基本的に人はhas_manyディストリビューションです。ディストリビューションは(とりわけ)パーセンテージ属性を持っています。特定の人物については、その分布は有効であるために合計100%でなければならない。これは私に "トランザクション"を叫ぶが、私は最初にバリデーターにショットを与えるべきであると思った。
私はこれをカスタムバリデータとして書きましたが、バリデータは既にデータベースに保存されているデータに対してのみ動作します。フォームによって提出されたパラメータをチェックしませんでした。言い換えれば、保存されたフォームから無効なパーセンテージを入力することができました。その後、モデル内の不良データのために後続の編集がすべて失敗しました。
def update_attributes(params)
retval = true
self.transaction do
retval = super
unless distributions_exactly_100?
retval = false
errors.add_to_base("Distribution must add up to exactly 100%")
raise ActiveRecord::Rollback
end
end
retval
end
retvalのビジネスは醜いですが、これは多かれ少なかれ、時には作品(保留中のディストリビューションのいくつかは、ときにそれをフォームから欠落している:
次は私がトランザクションを追加し、私のPersonモデルでupdate_attributesを拡張しましたエラーを見つけて再レンダリングします)。私のdistirbutionsの関連付けが以下のようにヘルパーメソッドで定義されている場合は、update_attributes()
(またはdistributions_exactly_100?
)のヘルパーメソッドを使用することができません。割り当てられたばかりのコミットされていないディストリビューションのセットで動作するのではなく、
has_many :distributions do
def for_month_and_year(month, year)
find :all, :conditions => ['month = ? and year = ?', month, year]
end
def total_for_month_and_year(month, year)
sum :percentage, :conditions => ['month = ? and year = ?', month, year]
end
...
def years_and_months
ds = find(:all, :order => 'year DESC, month DESC')
(ds.collect {|d| [d.year, d.month]}).uniq
end
end
私は考えることができる唯一の他の事はupdate_attributesへの途中で、テキストとして、自分自身をparamsは処理することです。しかし、それはちょうど間違っています。 :)
他の誰もが子供のコレクション全体で検証を行っていますか?それについて正しいことは何でしょうか?
はい、ありがとう、私はメモリ対DBの角度を計算したら、検証として呼び出される関数を書いています。 :) 妥当性検査が失敗したときに編集ビューを表示する方法にはまだ問題があります(一部の保留中の変更は失われていますが、すべてではありません)。 – korinthe