Cómo obtener el valor original de un atributo en Rails

96

¿Hay alguna manera de obtener el valor original de un atributo ActiveRecord (= el valor que se cargó desde la base de datos)?

Quiero algo como esto en un observador

before_save object
  do_something_with object.original_name
end

La tarea consiste en eliminar el objeto de una tabla hash (de hecho, moverlo a otra clave de la tabla) al actualizar.

Leonid Shevtsov
fuente

Respuestas:

243

Antes de los rieles 5.1

Agregar _wassu atributo le dará el valor anterior.

Para rieles 5.1+

Copiado de la respuesta de Lucas Andrade a continuación : https://stackoverflow.com/a/50973808/9359123


Agregar _wasestá obsoleto en rails 5.1, ahora debería agregar_before_last_save

Algo como:

before_save object
  do_something_with object.name_before_last_save
end

Devolverá el valor del nombre antes de su último guardado en la base de datos (funciona para guardar y crear)


La diferencia entre _wasy de _before_last_saveacuerdo con la documentación:

_fue fuente de documentos

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

_before_last_save fuente de documentos

def attribute_before_last_save(attr_name)
  mutations_before_last_save.original_value(attr_name)
end
Vincent
fuente
7
Por ejemplo: para self.context:self.context_was
Freedom_Ben
2
¿Dónde está la documentación para esto?
J Will
4
la documentación se puede encontrar en apidock.com/rails/ActiveModel/Dirty/attribute_was
hexinpeter
En la documentación, no hay ninguna advertencia de "desaprobación" para _was.
Rael Gugelmin Cunha
11

Para rieles 5.1+

Agregar _wasestá obsoleto en rails 5.1, ahora debería agregar_before_last_save

Algo como:

before_save object
  do_something_with object.name_before_last_save
end

Devolverá el valor del nombre antes de su último guardado en la base de datos (funciona para guardar y crear)


La diferencia entre _wasy de _before_last_saveacuerdo con la documentación:

_fue fuente de documentos

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

_before_last_save fuente de documentos

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

Puedes ver un mejor ejemplo aquí.

Lucas Andrade
fuente
1
attribute_washa quedado obsoleto en favor de attribute_in_database, mientras que attribute_before_last_savees un método completamente nuevo a partir de la versión 5.1 que no tiene equivalente en versiones anteriores de Rails. Fuente: github.com/rails/rails/pull/25337#issuecomment-225166796
ohaleck
8

ActiveRecord's attributes_before_type_cast método devuelve un hash de atributos antes de que se produzcan el encasillado y la deserialización.

John Topley
fuente