2016-06-14 42 views

risposta

17

È 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. "

Source

+4

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

+0

Grazie, ho aggiornato la mia risposta per aiutare i nuovi arrivati. – Leito

+1

Grazie per aver specificato la tecnica: abort per Rails 5. Dovrebbe davvero darmi una mano. – CanadaIT

2

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 

Documentation

+0

thnks, ma non voglio che rilanci nulla ... non fare niente –

+0

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. –

+1

In Rails 5, dovrai esplicitamente "raise: abort'. Potresti iniziare ora. – mwoods79

1

È possibile anche l'override del metodo #destroy:

def destroy 
    study_assignments.empty? ? super : self 
end