我以复杂形式使用多个子模型(la http://railsforum.com/viewtopic.php?id=28447)。表单很好,但我需要在接受表单数据到数据库之前验证子模型的集合的属性。我已经想出了一个主要工作,很笨拙的做法。似乎有必要有更好的方式,所以我要求建议...验证复杂形式的多个子模型的rails
基本上一个人has_many分布。分配(除其他外)具有百分比属性。对于一个给定的人,他们的分布必须总计100%才有效。这个尖叫“交易”给我,但我想我应该先给验证者一个镜头。
我试着把它作为自定义验证器来编写,但验证器只对已经保存到数据库的数据有效。它没有检查表单提交的参数。换句话说,我可以通过表单输入无效百分比,并保存起来,然后由于模型中已经存在错误的数据,所有后来的编辑都失败了。
接下来,我伸出我的Person模型update_attributes方法,增加了交易:
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企业是丑陋的,但是这或多或少作品(有时一些悬而未决的分布是从形式失踪,当它发现一个错误并重新渲染)。还有一个额外的细微差别让我相信这是一个糟糕的做法:如果我的分配关联是用辅助方法定义的,如下所示,我不能在我的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的过程中将参数本身作为文本处理。但那只是错误的。 :)
其他人对整个孩子集合进行验证?什么是正确的方式去做呢?
是的,谢谢,一旦我想出内存与DB角度,我写了一个函数作为验证。 :) 我仍然有问题,如果验证失败(一些挂起的更改丢失,但不是全部),编辑视图得到呈现,但这是一个不同的错误! – korinthe 2009-08-26 17:44:27