6

in Ruby on Rails 4, diciamo che un genitore ha molti figli. Quando il genitore viene eliminato, anche i bambini devono essere cancellati. Oltre a questo, il bambino non deve essere cancellato a meno che non sia un orfano. Come farlo?impediscono la cancellazione di un bambino a meno che non venga eliminato anche il genitore

ho provato con il seguente

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 

Con l'assegno before_destroy, tuttavia, nulla viene cancellato. C'è un modo per dire questo metodo se il motivo per cui viene chiamato è dovuto alla cancellazione del genitore?

È una cosa strana da chiedere? Voglio dire, prevenendo la cancellazione dei bambini.

+0

A meno che l'app non includa il codice che elimina direttamente i bambini, dovrebbe essere impossibile eliminarli direttamente, pur continuando a eliminarli come parte dell'eliminazione del genitore. Non capisco come ti trovi in ​​questo problema. Potresti per favore essere più specifico? – monfresh

+0

Hai ragione. Grazie. – user2553863

risposta

5

Lavorare da risposta di carpe da Rails: how to disable before_destroy callback when it's being destroyed because of the parent is being destroyed (:dependent => :destroy), provate questo:

bambini:

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 

principale:

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 

Abbiamo dovuto farlo perché stiamo usando Paranoia e dependent: delete_all sarebbe difficile eliminare piuttosto che soft-eliminarli. Il mio istinto mi dice che c'è un modo migliore per farlo, ma non è ovvio, e questo ha portato a termine il lavoro.

+0

Ho avuto lo stesso problema ma con la relazione has_one. Ho risolto in un modo leggermente diverso, ma sento anche che ci deve essere un modo migliore per farlo. [La mia soluzione] (http://stackoverflow.com/questions/23533552/rails-4-activerecord-prevent-dependent-destroy-if-owner-exists) – hector