c'è qualche modo, date certe condizioni, annullare la distruzione di un oggetto sul callback before_destroy del record attivo? GrazieRails - Annulla destroy on before_destroy callback
risposta
È necessario restituire false
.
Rails 5
"Annullamento callback
Se un before_ * callback Produce:. Interrompi, tutti i richiami più tardi e l'azione associata vengono cancellate"
rotaie 4 e inferiori
"Annullamento callback
Se un before_ * callback restituisce false, tutti i richiami successivi e l'azione associata sono annullate. Callback sono generalmente eseguiti nell'ordine in cui sono definiti, con l'eccezione dei callback definiti come metodi sul modello, che sono chiamati ultimi. "
Rails impacchi salva e distrugge in una transazione, quindi un raise
nella richiamata avrebbe funzionato:
class Post < ActiveRecord::Base
before_destroy :saveable?
def saveable?
if true
raise "Destroy aborted; you can't do that!"
end
end
end
sostituto true
per la vostra condizione.
Ecco l'output della console in forma abbreviata:
[1] pry(main)> Post.first.id
=> 1
[2] pry(main)> Post.first.destroy
RuntimeError: Destroy aborted; you can't do that!
[3] pry(main)> Post.first.id
=> 1
thnks, ma non voglio che rilanci nulla ... non fare niente –
ha senso. Poiché questo è un callback 'before_ *', funziona 'raise' o' false'. Il vantaggio di un 'raise' è che otterrai un messaggio chiaro che puoi tracciare nei log, invece che 'destroy' non sta accadendo tranquillamente. Quale scegliere dipende da quanto può essere inaspettato il tuo caso di fallimento. –
In Rails 5, dovrai esplicitamente "raise: abort'. Potresti iniziare ora. – mwoods79
Tornando false
è il modo per farlo correttamente:
before_destroy do
if self.some_condition?
return false
end
end
È possibile consultare la documentazione qui al punto 6 Halting Execution
. http://guides.rubyonrails.org/active_record_callbacks.html
È possibile anche l'override del metodo #destroy
:
def destroy
study_assignments.empty? ? super : self
end
con Rails 5, tornando falso non funziona più. Si dovrebbe 'lanciare (: abortire)' per impedire la cancellazione del record. Vedi [questo commento] (http://stackoverflow.com/questions/123078/how-do-i-validate-on-destroy-in-rails#comment59333149_123190) – RFVoltolini
Grazie, ho aggiornato la mia risposta per aiutare i nuovi arrivati. – Leito
Grazie per aver specificato la tecnica: abort per Rails 5. Dovrebbe davvero darmi una mano. – CanadaIT