#New_record? funkcja określa, czy rekord został zapisany. Ale zawsze jest fałszywe wafter_save
. Czy istnieje sposób ustalenia, czy rekord jest nowo utworzonym rekordem, czy starym z aktualizacji?
Mam nadzieję, że nie użyję innego wywołania zwrotnego, takiego jak before_create
ustawienie flagi w modelu lub wymaganie innego zapytania do bazy danych.
Każda rada jest mile widziana.
Edycja: trzeba to określić w after_save
podpięciu, a dla mojego konkretnego przypadku użycia nie ma updated_at
ani updated_on
sygnatury czasowej
ruby-on-rails
activerecord
activemodel
Aaron Qian
źródło
źródło
Odpowiedzi:
Chciałem użyć tego do
after_save
oddzwonienia.Prostszym rozwiązaniem jest użycie
id_changed?
(ponieważ się nie zmieniupdate
) lub nawetcreated_at_changed?
jeśli obecne są kolumny z datownikiem.Aktualizacja: jak wskazuje @mitsy, jeśli to sprawdzenie jest potrzebne poza wywołaniami zwrotnymi, użyj
id_previously_changed?
. Zobacz dokumentację .źródło
after_save
.id_changed?
będzie fałszywe po zapisaniu rekordu (przynajmniej poza hakami). W takim przypadku możesz użyćid_previously_changed?
Nie ma tu magii szyn, o której wiem, będziesz musiał to zrobić sam. Możesz to wyczyścić za pomocą wirtualnego atrybutu ...
W swojej klasie modelu:
źródło
Jeszcze inna opcja dla tych, którzy zrobienia mają
updated_at
timestamp:źródło
created_at
jest wyrównanieupdated_at
wafter_save
wywołaniu zwrotnym w dowolnym momencie, poza momentem jego utworzenia?”created_at
iupdated_at
będzie równy wafter_save
wywołaniu zwrotnym. We wszystkich innych sytuacjach nie będą one równe wafter_save
wywołaniu zwrotnym.Istnieje
after_create
wywołanie zwrotne, które jest wywoływane tylko wtedy, gdy rekord jest nowym rekordem, po jego zapisaniu . Istnieje równieżafter_update
wywołanie zwrotne do użycia, jeśli był to istniejący rekord, który został zmieniony i zapisany.after_save
Zwrotna jest wywoływana, w obu przypadkach, po alboafter_create
czyafter_update
jest tzw.Użyj,
after_create
jeśli chcesz, aby coś się wydarzyło po zapisaniu nowego rekordu.Więcej informacji tutaj: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
źródło
Ponieważ obiekt został już zapisany, musiałbyś spojrzeć na poprzednie zmiany. Identyfikator powinien się zmienić dopiero po utworzeniu.
Istnieje również zmienna instancji
@new_record_before_save
. Możesz uzyskać do niego dostęp, wykonując następujące czynności:Oba są dość brzydkie, ale pozwolą ci wiedzieć, czy obiekt został nowo utworzony. Mam nadzieję, że to pomoże!
źródło
after_save
wywołaniu zwrotnym przy użyciu Rails 4 i żaden z nich nie pracuje nad identyfikacją nowego rekordu.@object.previous_changes[:id].any?
jest to dość proste i eleganckie. U mnie działa po zaktualizowaniu rekordu (nie dzwonię z tegoafter_save
).@object.id_previously_changed?
jest trochę mniej brzydki.after_save
on Rails 4, na które wolałbyśchanges[:id]
raczej spojrzećprevious_changes[:id]
. To się jednak zmienia w Railsach5.1 (zobacz dyskusję na github.com/rails/rails/pull/25337 )previous_changes.key?(:id)
dla lepszego zrozumienia.Rails 5.1+ sposób:
źródło
Dla Rails 4 (sprawdzonych w 4.2.11.1) rezultatami
changes
iprevious_changes
metod są puste skróty{}
przy tworzeniu obiektów wewnątrzafter_save
. Więcattribute_changed?
metody takie jakid_changed?
nie będą działać zgodnie z oczekiwaniami.Ale możesz skorzystać z tej wiedzy i - wiedząc, że musi być co najmniej 1 atrybut
changes
aktualizacji - sprawdzić, czychanges
jest pusty. Gdy potwierdzisz, że jest pusty, musisz być podczas tworzenia obiektu:źródło
Lubię być konkretny, nawet jeśli o tym wiem
:id
normalnie nie powinno się to zmienić, aleZawsze taniej jest być konkretnym, zamiast znajdować bardzo dziwny, nieoczekiwany błąd.
Tak samo, jeśli oczekuję
true
flagi od niewiarygodnego argumentuOszczędza to wiele godzin, aby nie siedzieć na dziwnych błędach.
źródło