我的设置与下面类似。一切正常,但如果Employee
模型中的验证失败(调用自定义setter时),如何在update_attributes
模型上调用Employer
时触发它们?
<%= form_for @employer %>
<% @employer.employees.each do |employee| %>
<%= fields_for "employer[employee_attributes][]", employee do |e| %>
# FORM HERE
<% end %>
<% end %>
<% end %>
attr_accessible :employee_attributes
has_many :employees
def employee_attributes=(employee_attributes)
employee_attributes.each_pair{|id,attributes|
employee = Employee.find(id)
employee.update_attributes(attributes)
}
end
根据sockmonks的回答,请致电employee.update_attributes!(attributes)
而不是(最后的爆炸声)。这引起了例外。
然后在Employer
控制器
def update
@employer = Employer.find(:id)
begin
@employer.update_attributes(params[:employer])
rescue ActiveRecord::RecordInvalid => e
# Handle Error(s)
end
end
答案 0 :(得分:1)
而不是调用employee.update_attributes(attributes),而是使用employee.update_attributes!(attributes)。 (注意方法名称末尾的爆炸。)这样,如果任何员工无效,将引发异常。
现在,无论您是否正在调用该自定义setter,请务必将其包装在事务中,并挽救ActiveRecord :: RecordInvalid。然后,如果任何员工无效,整个交易将被回滚,您将有机会优雅地处理将验证错误传递回用户。
答案 1 :(得分:0)
您可以声明validates_associated验证来实现这一目标。
答案 2 :(得分:0)
正如ck3g指出的那样,您应该使用validates_associated
方法来验证您的子对象。 This answer就是一个例子。
Rails还有一个钩子,可以通过一次调用保存您的父对象和子对象(例如@employer.save
):accepts_nested_attributes_for。