使用reject_if的嵌套属性在渲染后不起作用

时间:2015-03-24 22:36:23

标签: ruby-on-rails validation nested-forms nested-attributes

我有一个带有嵌套属性的表单,我的模型代码包含:

accepts_nested_attributes_for :current_skills, :allow_destroy => true, reject_if: lambda {|attributes| attributes['skill_id'].blank?}

在我的控制器中:

def edit
  @employee = Employee.find(params[:id])
  ...
  @employee.current_skills.build
  @employee.desired_skills.build
end

def update
  ...
  @employee.current_skills.build
  @employee.desired_skills.build
  if @employee.update_attributes(employee_params)
    redirect_to @employee, notice: 'Employee was successfully updated.' 
  else
    render :edit
  end
end

如果验证失败,则不会保存预期的更新,并且正在呈现编辑视图。我的理解是我需要更新操作中的.build方法将空字段重新提供给表单(在我的测试中就是这种情况);但是,当包含.build方法来提供字段时,它们不会被第二次提交上的模型拒绝,而是被保存到数据库中(不像我期望的那样)。

验证失败后是否有更好的方法来提供字段,但如果空白则拒绝它们?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

如果我是你,我会这样做:

def update
  ...
  if @employee.update_attributes(employee_params)
    redirect_to @employee, notice: 'Employee was successfully updated.' 
  else
    @employee.current_skills.build if @employee.current_skills.empty?
    @employee.desired_skills.build if @employee.desired_skills.empty?
    render :edit
  end
end

我希望它有所帮助。

修改:阅读完您的评论后,我必须说:您的代码很好,而且必须正常工作。标准是不是在update方法中构建一个关联,我不明白为什么你需要它(如果是测试,从主代码中删除并处理测试)。此时,您必须检查服务器日志中的参数,或者设置skill_id值的模型中的回调。顺便说一句,如果保存的记录的skill_id不是零,那么accept_nested_attributes_for工作正常。