Jos*_*rco 19 ruby-on-rails ruby-on-rails-3.1
我有两个班:父母和孩子
儿童:
belongs_to :parent
Run Code Online (Sandbox Code Playgroud)
和
亲
has_many :children, :dependent => :destroy
Run Code Online (Sandbox Code Playgroud)
问题是我想检查总是至少有一个孩子存在,所以我在Child中有一个before_destroy方法,如果它是属于其父项的唯一子项,则中止destroy.
并且,如果我想要销毁父节点,它将在每个子节点上调用before_destroy回调,但是当有一个子节点时,它将中止销毁,因此父节点永远不会被销毁.
如果孩子因为父母没有被销毁,我怎么能告诉孩子调用before_destroy回调呢?
谢谢!
Ale*_*x D 11
has_many :childs, :dependent => :delete_all
Run Code Online (Sandbox Code Playgroud)
这将删除所有孩子而不运行任何钩子.
您可以在以下网址找到相关文档:http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many
如果您在 before_destroy 方法上将 prepend 设置为 true,则 carp 的上述答案将起作用。尝试这个:
孩子:
belongs_to :parent
before_destroy :prevent_destroy
attr_accessor :destroyed_by_parent
...
private
def prevent_destroy
if !destroyed_by_parent
self.errors[:base] << "You may not delete this child."
return false
end
end
Run Code Online (Sandbox Code Playgroud)
家长:
has_many :children, :dependent => :destroy
before_destroy :set_destroyed_by_parent, prepend: true
...
private
def set_destroyed_by_parent
children.each{ |child| child.destroyed_by_parent = true }
end
Run Code Online (Sandbox Code Playgroud)
我们必须这样做,因为我们使用的是 Paranoia,并且dependent: delete_all
会硬删除而不是软删除它们。我的直觉告诉我有一种更好的方法可以做到这一点,但它并不明显,而且这可以完成工作。
在Rails 4中,您可以执行以下操作:
class Parent < AR::Base
has_many :children, dependent: :destroy
end
class Child < AR::Base
belongs_to :parent
before_destroy :check_destroy_allowed, unless: :destroyed_by_association
private
def check_destroy_allowed
# some condition that returns true or falls
end
end
Run Code Online (Sandbox Code Playgroud)
这样,当destroy
直接在子级上check_destroy_allowed
调用时,将运行该回调,但在destroy
父级上调用时,则不会。
归档时间: |
|
查看次数: |
3070 次 |
最近记录: |