ruby-on-rails - Rails 中更新验证失败后嵌套属性不会被销毁

标签 ruby-on-rails ruby-on-rails-3 nested-attributes

我自己正在努力解决这个问题,所以我希望我能很好地解释它。我有一个带有嵌套模型的表单。简化版本如下(使用 Rails 3.0.13);

#parent.rb

class Parent < ActiveRecord::Base
  has_many :children, :dependent => destroy
  accepts_nested_attributes_for :children, :allow_destroy => true
  validates_presence_of :thing
  validate :children_unique

  def children_unique
    errors[:base] << "You have the same child listed more than once!" if self.children.map{|x| [child.name, child.age]} != self.children.map{|x| [child.name, child.age]}.uniq
  end
end


#child.rb

class Child < ActiveRecord::Base
  belongs_to :parents
end

#parents_controller.rb

class ParentsController < ApplicationController
  load_and_authorize_resource :parent   #Using cancan for authorization. This calls @parent = Parent.find(params[:id]); authorize! :update, @parent; at the start of the update method

  def update
    if @parent.update_attributes(params[:operation])
      redirect_to @parent.admission, :notice => 'Operation was updated successfully'
    else
      flash.now[:warning] = "Parent was NOT updated!"
      render :action => "edit"
    end
  end
end

到目前为止,一切都相当标准。我的表格也是以非常标准的方式设置的。我调用parent_form.fields_for :children并为 fields_for block 中的子级渲染部分内容。每个子部分表单都包含一个删除链接,当单击该链接时,将使用 JavaScript 设置隐藏字段,因此 _destroy 的属性将设置为“1”,并且部分会从 View 中隐藏。

这在大多数情况下效果很好,但我发现的奇怪问题如下;

如果我正在编辑已经有 2 个子级的现有父级,并且删除其中 1 个子级,然后将“thing”设置为空白,则表单将按预期失败验证(因为“thing”不存在)并且编辑 View 被重新渲染。从结果来看,我删除的 child 又出现了!它的隐藏 _destroy 字段设置为“true”,如果我再次填写“thing”并提交表单,则更新后的父级只有 1 个子级。

我通过向嵌套子 div 添加条件样式标签来解决这个问题 <div class='fields'<%= " style='display: none;'" if f.object._destroy %>>因此,如果在尝试更新记录之前将其删除,它将不再出现。这实现了其目标,但是,如果我这样做并提交表单而不更正空的“事物”字段,那么模型再次验证失败,并且在出现的下一个编辑表单中,我添加一个与之前删除的表单相同的新子表单并填写“事物”字段,该模型现在失败 children_unique即使第一个相同子项的 _delete 属性设置为“true”,也会进行验证。

显然,我在这里陷入了困境,并且尝试了多种替代方法和修改,这是迄今为止我想出的最好方法。它非常非常接近,但我仍然有这种奇怪的边缘情况,在实践中可能永远不会真正发生,但这表明我不太了解我的 Controller 和模型交互的方式。

有人可以纠正我吗?

最佳答案

您应该将删除链接设置为对 Controller 的 ajax 调用,该 Controller 立即删除子项并从页面中删除它的标记,这样,即使验证确实失败,您也已经删除了它,并且没有这两个问题将会发生。

关于ruby-on-rails - Rails 中更新验证失败后嵌套属性不会被销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10967560/

相关文章:

ruby-on-rails - Ruby on Rails 中的 JSON 格式显示

ruby-on-rails - 如何使用具有动态路段的 Rails 3 路线

ruby-on-rails - 嵌套属性未插入表中

ruby-on-rails - 应用程序的名称是否可以作为变量使用?

ruby-on-rails - 从 ruby 中排列的哈希切片成 block

ruby-on-rails - Rails 返回 html 而不是 json

ruby-on-rails - Rails 3 路由到错误的 Controller

ruby-on-rails-3 - 僵尸路轨5级挑战5

ruby-on-rails - AcitveRecord 不会接受_nested_attributes_for 具有嵌套现有记录的新关联记录

ruby-on-rails - Rails-更新nested_attributes不适用于一对多关系