I've got two models.
- 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 = Parent.new :name => "Jose"
parent.save
#=> false
parent.children_attributes = [{:name => "Pedro"}, {:name => "Emmy"}]
parent.save
#=> true

验证工作.然后我们将通过_destroy属性摧毁 children :

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

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

实际上,这是因为在我通过_delete从父对象中删除子对象之后,children方法仍然会在我重新加载之前返回已销毁的对象,所以验证通过了:

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 filter添加到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相关问答推荐

Rails 7.1,登录到STDOUT和LOG/Production.log

显示每个 rspec 示例的运行时

Rails - 按连接表数据排序

2个空格或1个制表符,Rails社区的缩进标准是什么?

如何从 Ruby on Rails 应用程序返回正确的 HTTP 错误代码

耙路由错误缺少:路由定义上的操作键

如何在rails中发回js.haml

如何使用失败try 次数使设计可锁定

Rails 助手应该假设实例变量存在还是应该将它们作为参数接收?

使用回形针调整图像大小

为什么 respond_with 被从 rails 4.2 移除到它自己的 gem 中?

将图标添加到 Rails 应用程序

Rails Rake 任务 - 访问模型类

登录delay_job?

在 RoR 中引用同一个表的多个外键

Rails 范围为 IS NOT NULL 并且不为空/空白?

如何在每个操作的基础上禁用 Ruby on Rails 的日志(log)记录?

Rails,Docker:主机不存在:默认

您如何查看 ruby​​ 中的调用堆栈示例?

ruby on rails 如何处理 NaN