Jak uzyskać oryginalną wartość atrybutu w Railsach

96

czy istnieje sposób na uzyskanie oryginalnej wartości atrybutu ActiveRecord (= wartość załadowana z bazy danych)?

Chcę czegoś takiego w obserwatorze

before_save object
  do_something_with object.original_name
end

Zadanie polega na usunięciu obiektu z tablicy skrótów (w rzeczywistości przeniesieniu go do innego klucza w tabeli) po aktualizacji.

Leonid Shevtsov
źródło

Odpowiedzi:

243

Przed szynami 5.1

Dołączenie _wasdo twojego atrybutu da ci poprzednią wartość.

Do szyn 5.1+

Skopiowano z odpowiedzi Lucasa Andrade'a poniżej : https://stackoverflow.com/a/50973808/9359123


Dołączanie _wasjest przestarzałe w railsach 5.1, teraz powinieneś dołączyć_before_last_save

Coś jak:

before_save object
  do_something_with object.name_before_last_save
end

Zwróci wartość nazwy przed ostatnim zapisem w bazie danych (działa przy zapisywaniu i tworzeniu)


Różnica między _wasi _before_last_savezgodnie z dokumentacją:

_był źródłem z docs

def attribute_was(attr)
  attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
end

_before_last_save źródło z dokumentów

def attribute_before_last_save(attr_name)
  mutations_before_last_save.original_value(attr_name)
end
Vincent
źródło
7
Np .: za self.context:self.context_was
Freedom_Ben
2
Gdzie jest dokumentacja?
j będzie
4
dokumentację można znaleźć na apidock.com/rails/ActiveModel/Dirty/attribute_was
hexinpeter
W dokumentacji nie ma ostrzeżenia o „wycofaniu” dla _was.
Rael Gugelmin Cunha
11

Do szyn 5.1+

Dołączanie _wasjest przestarzałe w railsach 5.1, teraz powinieneś dołączyć_before_last_save

Coś jak:

before_save object
  do_something_with object.name_before_last_save
end

Zwróci wartość nazwy przed ostatnim zapisem w bazie danych (działa przy zapisywaniu i tworzeniu)


Różnica między _wasi _before_last_savezgodnie z dokumentacją:

_był źródłem z docs

def attribute_was(attr)
  attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
end

_before_last_save źródło z dokumentów

def attribute_before_last_save(attr_name)
  mutations_before_last_save.original_value(attr_name)
end

Można zobaczyć lepszy przykład tutaj

Lucas Andrade
źródło
1
attribute_waszostał uznany za przestarzały na korzyść attribute_in_database, podczas gdy attribute_before_last_savejest to zupełnie nowa metoda od 5.1, która nie ma odpowiednika we wcześniejszych wersjach Railsów. Źródło: github.com/rails/rails/pull/25337#issuecomment-225166796
ohaleck