Rails在update_attributes期间形成自定义setter的验证?

时间:2013-05-08 17:29:11

标签: ruby-on-rails ruby activerecord

我的设置与下面类似。一切正常,但如果Employee模型中的验证失败(调用自定义setter时),如何在update_attributes模型上调用Employer时触发它们?

视图/雇主/ _form.html.erb

<%= form_for @employer %>
    <% @employer.employees.each do |employee| %>
        <%= fields_for "employer[employee_attributes][]", employee do |e| %>
            # FORM HERE
        <% end %>
    <% end %>
<% end %>

模型/ employer.rb

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控制器

控制器/ employers_controller.rb

def update
    @employer = Employer.find(:id)
    begin
        @employer.update_attributes(params[:employer])
    rescue ActiveRecord::RecordInvalid => e
        # Handle Error(s)
    end
end

3 个答案:

答案 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