Необходимо проверить, изменился ли блок атрибутов перед обновлением в Rails 3.
улица1, улица2, город, штат, почтовый индекс
Я знаю, что мог бы использовать что-то вроде
if @user.street1 != params[:user][:street1]
then do something....
end
Но этот кусок кода будет очень долго. Есть ли более чистый способ?
Так я решил проблему проверки изменений в нескольких атрибутах.
changed
Метод возвращает массив атрибутов измененных для этого объекта.Оба
@user.changed
иattrs
являются массивами, поэтому я могу получить пересечение (см.ary & other ary
Метод). Результатом пересечения является массив. Вызываяany?
массив, я получаю истину, если есть хотя бы одно пересечение.Также очень полезно,
changed_attributes
метод возвращает хэш атрибутов с их исходными значениями иchanges
возвращает хэш атрибутов с их исходными и новыми значениями (в массиве).Вы можете проверить APIDock, для каких версий поддерживаются эти методы.
http://apidock.com/rails/ActiveModel/Dirty
источник
if attrs.any?{|attr| @user.send("#{attr}_changed?")}
Когда я хочу проверить, не изменился ли один из нескольких различных атрибутов - конечно, я делаю это только с теми атрибутами, которые я определил сам, потому что я не люблю бросать пользовательские параметры вsend
метод. ;)ActiveModel::Dirty
не работал для меня, потому что@model.update_attributes()
скрыл изменения. Вот как я обнаружил изменения вupdate
методе в контроллере:Если вы пытаетесь обнаружить много изменений атрибутов, это может привести к путанице. Вероятно, не следует делать это в контроллере, но ме.
источник
previous_changes
что также доступно по умолчанию.#update_attributes
не скрывает изменения Сохраняет запись, поэтому модель обновляется и изменений нет. Вам нужно изменить поле в модели и проверить егоchanged?
перед сохранением. то есть. @ model.field = 'foo' или@model.attributes = @model.attributes.merge(params[:model])
Для рельсов 5.1+ обратные вызовы
Начиная с Ruby on Rails 5.1, методы
attribute_changed?
иattribute_was
ActiveRecord устарелиИспользуйте
saved_change_to_attribute?
вместоattribute_changed?
Больше примеров здесь
источник
Приведенные выше ответы лучше, но, тем не менее, для понимания у нас есть и другой подход: давайте изменили значение столбца 'catagory' для объекта (@design),
.Changes вернет хеш с ключом в качестве имени столбца и значения в виде массива с двумя значениями [old_value, new_value] для каждого столбца. Например, категория выше была изменена с «ABC» на «XYZ» в @design,
Для смены ссылок в ROR
источник