8

Wie Sie wissen, werden before_save Rückrufe vor before_create Rückrufe ausgeführt.ist: on =>: gültig für einen Rückruf vor dem Speichern in Rails 3.2.3

Daher haben einige Leute vorgeschlagen, dass in besser wäre before_save :method, :on => :create anstelle von before_create zu verwenden, so dass die Callback-Methode zur richtigen Zeit in Bezug auf andere Rückrufe (wie Autosave-Rückrufe) ausgeführt wird. Siehe beispielsweise Pivotal Labs blog post und this StackOverflow answer.

Allerdings, so weit ich sagen kann, erreicht die :on => :create Option nicht den gewünschten Effekt auf einen Rückruf before_save. Mit anderen Worten, der Rückruf wird für jeden Speichervorgang ausgeführt, unabhängig davon, ob er erstellt wurde oder nicht.

Die :on => :create Option tut für before_validation Rückrufe als gültig erscheinen, though.

Könnte jemand bestätigen, ob die :on => :create für eine before_save arbeiten soll? Hat es in früheren Versionen von Rails funktioniert und ist jetzt defekt, oder sind die oben genannten Links einfach falsch?

Angenommen, :on => :create ist nicht gültig, ist das folgende akzeptabel, und/oder gibt es einen besseren Weg?

before_save :callback_method, :if => :new_record? 

Vielen Dank.

+0

legte ich eine PR für Rails strenge Überprüfung der Argumente hinzuzufügen: https://github.com/rails/rails/pull/30919 – seanlinsley

Antwort

15

Sie haben recht, es gibt keine :on Option für before_save Rückruf. Aber ich verstehe nicht, warum before_save anstelle von before_create verwenden. before_create Rückruf wird direkt nach before_save aufgerufen werden.

Natürlich können Sie before_save :callback_method, :if => :new_record? verwenden. Aber ich persönlich mag diese Lösung nicht - was, wenn ich Bedingungen in der :if Option hinzufügen muss?

Wenn eine Abhängigkeit zwischen before_save und before_create Callbacks haben, würde ich vorschlagen, 2 Callbacks zu kombinieren. Zum Beispiel (Pseudo-Code):

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

Dank für Ihre Antwort, und insbesondere für die Bestätigung Das ': on =>: create' ist nicht gültig. Callbacks zu kombinieren klingt nach einer guten Idee im allgemeinen Fall, aber ich bin mir nicht sicher, ob es gut für den speziellen Fall ist, Daten für einen Callback zu präparieren, der von einer Autosave-Assoziation erstellt wurde, oder? – Nathan

+1

In Bezug auf Ihre Frage, warum ich before_save anstelle von before_create verwenden möchte, wird dies in dem Blogpost, auf den ich verwiesen habe, gut erklärt. Ein Callback wird von Core-Rails-Code über eine Autosave-Verknüpfung erstellt. Der Rückruf, den ich erstellen möchte, muss vor dem automatischen Rückruf ausgeführt werden, und ein vorheriger Rückruf würde zu spät erfolgen. – Nathan

+1

Es ist schade, dass 'before_save: on =>: create' stumm schlägt. Es wäre schön, wenn es entweder funktioniert oder eine Ausnahme auslöst. –

Verwandte Themen