8

Come sapete, le chiamate before_save vengono eseguite prima delle chiamate before_create.È: on =>: crea una valida per un callback before_save in Rails 3.2.3

Pertanto, alcune persone hanno suggerito che in sarebbe meglio utilizzare before_save :method, :on => :create invece di before_create in modo che il metodo di callback viene eseguito al momento giusto in relazione ad altri callback (come callback salvataggio automatico). Vedere, ad esempio, questo Pivotal Labs blog post e this StackOverflow answer.

Tuttavia, per quanto posso dire, l'opzione :on => :create non ottiene l'effetto desiderato su un callback before_save. In altre parole, la richiamata viene eseguita per ogni salvataggio indipendentemente dal fatto che si tratti di una creazione o meno.

L'opzione :on => :createfa sembrano essere valido per before_validation callback, però.

Qualcuno potrebbe confermare se il :on => :create deve funzionare per un before_save? Funzionava nelle versioni precedenti di Rails e ora è rotto, o i link di cui sopra sono semplicemente sbagliati?

Supponendo che :on => :create non sia valido, è il seguente accettabile e/o c'è un modo migliore?

before_save :callback_method, :if => :new_record? 

Grazie.

+0

ho presentato un PR per Rails aggiungere rigoroso controllo argomento: https://github.com/rails/rails/pull/30919 – seanlinsley

risposta

15

Hai ragione, non c'è l'opzione :on per il callback before_save. Ma, non capisco, perché utilizzare before_save anziché before_create. before_create la chiamata verrà richiamata subito dopo before_save.

Naturalmente, è possibile utilizzare before_save :callback_method, :if => :new_record?. Ma personalmente non mi piace questa soluzione - cosa succede se ho bisogno di aggiungere condizioni nell'opzione :if?

Se si ha una dipendenza tra i callback before_save e before_create, si consiglia di combinare 2 callback. Per esempio (pseudocodice):

class MyModel < ActiveRecord::Base 
    before_create :prepare_x 
    before_save :do_something_with_x 

    def prepare_x 
    @x = 10 
    end 


    # will not work, because `prepare_x` called after `do_something_with_x` 
    def do_something_with_x 
    @a = 100/@x 
    end 
end 

# || 
# || 
# \/ 

class MyModel < ActiveRecord::Base 

    before_save :do_something_with_x 

    def do_something_with_x 
    @x = 10 if new_record? 
    @a = 100/@x 
    end 
end 
+0

grazie per la risposta, e in particolare per la conferma that ': on =>: create' non è valido. Combinare i callback suona come potrebbe essere una buona idea nel caso generale, ma non sono sicuro che si applica bene al caso specifico di provare a preparare i dati per un callback creato da una associazione di salvataggio automatico, vero? – Nathan

+1

Riguardo alla tua domanda sul perché voglio usare before_save invece di before_create: questo è spiegato bene nel post del blog a cui ho fatto riferimento. Un callback viene creato dal codice Rails principale tramite un'associazione di salvataggio automatico. Il callback che voglio creare deve essere eseguito prima della richiamata autosave e una callback before_create si verifica troppo tardi. – Nathan

+1

È un peccato che 'before_save: on =>: create' non funzioni in modo silenzioso. Sarebbe bello se funzionasse o gettasse un'eccezione. –

Problemi correlati