Jaka jest różnica między „after_create” a „after_save” i kiedy użyć którego?

124

Czy after_createi after_savetakie same jak w przypadku funkcji?

Chcę wykonać operację na e-mailu użytkownika po utworzeniu jego konta.

Chcę wykonać tę operację, gdy jest zapisana w bazie danych.

który jest lepszy w użyciu: after_createlub after_save?

Swapnil Chincholkar
źródło

Odpowiedzi:

212

after_create działa tylko raz - zaraz po utworzeniu rekordu.

after_save działa za każdym razem, gdy zapisujesz obiekt - nawet jeśli aktualizujesz go wiele lat później

Więc jeśli chcesz wykonać tę operację e-mail tylko raz (i nigdy więcej), użyj after_create.

Jeśli chcesz to robić za każdym razem, gdy obiekt jest zapisywany, zrób to wafter_save

Taryn East
źródło
2
czytelnicy powinni pamiętać, że zgodnie z dokumentacją ActiveRecord's update_allnie wywołuje żadnych wywołań zwrotnych, w tymafter_*
user2426679
93

Z dokumentów :

after_create()

Jest wywoływana po Base.savedla nowych obiektów, które nie zostały jeszcze zapisane (brak rekordu).

after_save()

Jest wywoływana po Base.save (niezależnie od tego, czy jest to zapis tworzenia, czy aktualizacji).

Michael Kohl
źródło
1
after_save()

Działa dobrze, gdy musisz zapisywać modele, które nie zapisują zbyt często. W tym konkretnym przykładzie częstej zmiany rekordów byłoby wskazane użycie

 after_commit()

upewnij się, że model został zapisany w bazie danych przed wykonaniem akcji after_commit: oblicz_kredyt_punkt

def calculate_credit_score
     #Call a Cron job
end
pensebien
źródło
Radzisz używać, after_commitale nie wyjaśniaj dlaczego. Czy możesz to rozwinąć? Zauważ, że after_commitdziała przy tworzeniu, aktualizowaniu i niszczeniu. Dokumenty: apidock.com/rails/ActiveRecord/Transactions/ClassMethods/… Więc to nie jest to samo zachowanie, co after_savenaprawdę chcesz wywołać to cron_job po zniszczeniu rekordu? Czy w przypadku operacji wysłać wiadomość e-mail do usuniętego użytkownika? Uważaj z używaniemafter_commit
rmcsharry
after_commitdziała na tych operacjach CRUD, więc jeśli w jego przypadku wiadomość e-mail jest często aktualizowana, łatwiej byłoby połączyć akcję dla konkretnego wywołania zwrotnego. W moim przypadku użyłemafter_commit : calculate_profile_update, on: :update
pensebien