问题
in Ruby on Rails 4, let's say a parent has many children. When the parent is deleted, the children must also be deleted. Other than that, the child shall not be deleted unless it is an orphan. How to do that?
I tried with the following
class Parent < ActiveRecord::Base
has_many :children, inverse_of: :parent, dependent: :destroy
end
class Child < ActiveRecord::Base
belongs_to :parent, inverse_of: :children
before_destroy :checks
private
def checks
not parent # true if orphan
end
end
With the before_destroy check, however, nothing gets deleted. Is there any way of telling this method if the reason of being called is because parent deletion?
Is this an odd thing to ask for? I mean, preventing deletion of childs.
回答1:
Working from carp's answer from Rails: how to disable before_destroy callback when it's being destroyed because of the parent is being destroyed (:dependent => :destroy), try this:
Child:
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
Parent:
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
We had to do this because we're using Paranoia, and dependent: delete_all
would hard-delete rather than soft-delete them. My gut tells me there's a better way to do this, but it's not obvious, and this gets the job done.
来源:https://stackoverflow.com/questions/23064049/rails-prevent-deletion-of-child-unless-parent-is-being-deleted-also