Es necesario verificar si un bloque de atributos ha cambiado antes de actualizar en Rails 3.
calle1, calle2, ciudad, estado, código postal
Sé que podría usar algo como
if @user.street1 != params[:user][:street1]
then do something....
end
Pero ese código será REALMENTE largo. ¿Hay una manera más limpia?
Así es como resolví el problema de verificar los cambios en múltiples atributos.
El
changed
método devuelve una matriz de los atributos modificados para ese objeto.Ambos
@user.changed
yattrs
son matrices para que pueda obtener la intersección (verary & other ary
método). El resultado de la intersección es una matriz. Al llamarany?
a la matriz, me vuelvo verdadero si hay al menos una intersección.También es muy útil, el
changed_attributes
método devuelve un hash de los atributos con sus valores originales ychanges
devuelve un hash de los atributos con sus valores originales y nuevos (en una matriz).Puede verificar APIDock para saber qué versiones admiten estos métodos.
http://apidock.com/rails/ActiveModel/Dirty
fuente
if attrs.any?{|attr| @user.send("#{attr}_changed?")}
Cuando quiero verificar si uno de los diferentes atributos ha cambiado. Por supuesto, solo hago esto con atributos que yo mismo he definido, porque no me gusta incluir parámetros de usuario en unsend
método. ;)ActiveModel::Dirty
no funcionó para mí porque@model.update_attributes()
escondió los cambios. Así es como detecté cambios en unupdate
método en un controlador:Sin embargo, si intenta detectar muchos cambios en los atributos, podría ser complicado. Probablemente no debería hacer esto en un controlador, pero meh.
fuente
previous_changes
que también está disponible de forma predeterminada.#update_attributes
No oculta los cambios. Guarda el registro, por lo que el modelo se actualiza y no hay cambios. Debe cambiar el campo en el modelo y verificarchanged?
antes de guardarlo. es decir. @ model.field = 'foo' o@model.attributes = @model.attributes.merge(params[:model])
Para rieles 5.1+ devoluciones de llamada
A partir de Ruby on Rails 5.1, los métodos
attribute_changed?
yattribute_was
ActiveRecord quedarán en desusoUsar en
saved_change_to_attribute?
lugar deattribute_changed?
Más ejemplos aquí.
fuente
Las respuestas anteriores son mejores, pero para el conocimiento también tenemos otra aproximación, cambiemos el valor de la columna 'catagory' para un objeto (@design),
Los .changes devolverán un hash con la clave como nombre de columna y los valores como una matriz con dos valores [old_value, new_value] para cada columna. Por ejemplo, la categoría de arriba se cambia de 'ABC' a 'XYZ' de @design,
Para referencias cambiar en ROR
fuente