ruby-on-rails - 嵌套模型和父验证

标签 ruby-on-rails ruby nested-attributes

我有两个模型。
- Parent has_many Children;
- Parent accepts_nested_attributes_for Children;

class Parent < ActiveRecord::Base
  has_many :children, :dependent => :destroy
  accepts_nested_attributes_for :children, :allow_destroy => true
  validates :children, :presence => true
end

class Child < ActiveRecord::Base
  belongs_to :parent
end

我使用验证来验证每个 parent 是否存在 child ,因此我无法保存没有 child 的 parent 。

parent = Parent.new :name => "Jose"
parent.save
#=> false
parent.children_attributes = [{:name => "Pedro"}, {:name => "Emmy"}]
parent.save
#=> true

验证工作。然后我们将通过 _destroy 属性销毁 child :

parent.children_attributes = {"0" => {:id => 0, :_destroy => true}}
parent.save
#=> true !!!
parent.reload.children
#=> []

所以我可以通过嵌套表单销毁所有子项,验证将通过。

实际上发生这种情况是因为在我通过 _delete 从我的父对象中删除子对象后,子对象方法仍然在我重新加载它之前返回已销毁的对象,因此验证通过:

parent.children_attributes = {"0" => {:id => 0, :_destroy => true}}
parent.save
#=> true !!!
parent.children
#=> #<Child id:1 ...> # It's actually deleted
parent.reload.children
#=> []

这是错误吗?

问题是什么。问题是修复它的最佳解决方案。我的方法是将 before_destroy 过滤器添加到 Child 以检查它是否是最后一个。但它使系统变得复杂。

最佳答案

这可能对您有用,但我感觉还有更好的答案。对我来说这听起来像是一个错误。

class Parent < ActiveRecord::Base
  validate :must_have_children

  def must_have_children
    if children.empty? || children.all?(&:marked_for_destruction?)
      errors.add(:base, 'Must have at least one child')
    end
  end
end

关于ruby-on-rails - 嵌套模型和父验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5144527/

相关文章:

ruby - 尝试理解一些有关类和数组问题的内容

ruby-on-rails - rails4 collection select with has_many 通过关联和嵌套模型形式

ruby-on-rails - Rails 3 + JQuery 文件上传 + 嵌套模型

ruby-on-rails - 具有多态has_one模型的嵌套属性

ruby-on-rails - Rails, Facebook API, Koala gem — 获取页面为 'Like' 的用户的所有配置文件

ruby-on-rails - 红矿: send mail via gmail error SSL_connect or STARTTLS

ruby-on-rails - Rails 项目,在使用 capybara 进行测试时:ArgumentError: 未使用的参数传递给 Capybara::Queries::SelectorQuery : [4]

ruby-on-rails - 从 Rails 2.3 升级到 Rails 4.0

mysql - 使用 ruby​​ 访问现有的 MySql 数据库(路径?)

RubyMine - 关键字 'require' 显示为红色,但应用程序运行正常