Gibt es einen Unterschied zwischen:after_create: foo vs after_commit: bar,: auf =>: create
after_create :after_create
und after_commit :after_commit_on_create, :on => :create
diese austauschbar verwendet werden können?
Gibt es einen Unterschied zwischen:after_create: foo vs after_commit: bar,: auf =>: create
after_create :after_create
und after_commit :after_commit_on_create, :on => :create
diese austauschbar verwendet werden können?
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
.
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
Bedeutet dies, dass, wenn after_commit hebt und Ausnahme dann wird es nicht die vorherige engagierte Abfrage Rollback –
Correct (Erstellung Teil?) -, sobald die Transaktion nicht mehr –
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