2013-04-01 5 views

Antwort

69

Sie sind nicht austauschbar. Der Hauptunterschied ist, wenn der Rückruf ausgeführt wird. Im Fall von after_create wird dies immer vor dem Aufruf an save (oder create) zurückgegeben.

Schienen wickelt alle save innerhalb einer Transaktion und die Vorher/Nachher-Callbacks laufen innerhalb dieser Transaktion (eine Konsequenz daraus ist, dass, wenn eine Ausnahme in einem after_create ausgelöst wird, die Sicherung zurückgesetzt wird). Mit after_commit wird Ihr Code erst ausgeführt, nachdem die äußerste Transaktion festgeschrieben wurde. Dies können die erstellten oder von Ihnen angelegten Transaktionsschienen sein (zB wenn Sie innerhalb einer Transaktion mehrere Änderungen vornehmen möchten).

Zum Zeitpunkt, als after_save/create ausgeführt wird, konnte Ihre Sicherung noch zurückgesetzt werden und (standardmäßig) wird nicht für andere Datenbankverbindungen sichtbar (z. B. eine Hintergrundaufgabe wie sidekiq). Eine Kombination dieser 2 ist in der Regel die Motivation für die Verwendung von after_commit.

+8

Bedeutet dies, dass, wenn after_commit hebt und Ausnahme dann wird es nicht die vorherige engagierte Abfrage Rollback –

+9

Correct (Erstellung Teil?) -, sobald die Transaktion nicht mehr –

+11

Hinweis gerollt werden comitted wurde, kann wieder, dass bei der Einstellung eine asynchrone Task (zB über sidekiq), die die 'id' des zu erstellenden Objektes verwendet, sollte man 'after_commit, ... on:: create' verwenden, da man mit' after_create' eine 'ActiveRecord :: RecordNotFound' Exception bekommen kann . Das ist uns gerade passiert. – Dschee

3

Es gibt einen großen Unterschied zwischen diesen beiden hinsichtlich der Assoziationen. after_create wird aufgerufen, sobald eine Einfügeabfrage für das angegebene Objekt und vor den Insert-Abfragen der Zuordnungen des Objekts ausgelöst wird. Dies bedeutet, dass die Werte der zugehörigen Objekte direkt in after_create callbacks ohne update query geändert werden können.

class Post < ActiveRecord::Base 
    has_one :post_body 
    after_create :change_post_body 

    def change_post_body 
    self.post_body.content = "haha" 
    #No need to save 
    end 
end 
Verwandte Themen