Rails模型回调(创建/更新后)attribute_w不起作用



我正在将rails 5.1应用程序迁移到rails 5.2.1。在我的模型中,我在创建或更新模型后使用回调来创建活动日志。不幸的是,todo.nametodo.name_was总是相同的——即当前值。这适用于每个属性和每个模型。此外,changed?返回false。

我是不是错过了什么?

我非常感谢你的帮助!

在after_create/update回调中不会得到attribute_was,因为此时数据库中的记录已经更改。

您可以在after_create/update回调中使用previous_changes

下面是一个例子。

考虑,用户模型:

class User < ApplicationRecord
before_update :check_for_changes
after_update :check_for_previous_changes
private def check_for_changes
puts changes # => {"name"=>["Nimish Gupta", "Nimish Mahajan"], "updated_at"=>[Tue, 20 Nov 2018 00:02:14 PST -08:00, Tue, 20 Nov 2018 00:06:15 PST -08:00]}
puts previous_changes # => {} At this point this will be empty beacuse changes are not made to DB yet
puts name_was # => "Nimish Gupta" i.e the original name
puts name # => "Nimish Mahajan" i.e the new name which will be going to save in DB
end
private def check_for_previous_changes
puts changes # => {}
# Please note `changes` would be empty now because record have been saved in DB now
# but you can make use of previous_changes method to know what change has occurred.
puts previous_changes # => {"name"=>["Nimish Gupta", "Nimish Mahajan"], "updated_at"=>[Tue, 20 Nov 2018 00:06:15 PST -08:00, Tue, 20 Nov 2018 00:08:07 PST -08:00]}
puts name_was # => "Nimish Mahajan" i.e the new name which have been saved in DB
puts name # => "Nimish Mahajan" i.e the new name which have been saved in DB
# to get the previous name if after_create/update callback, Please use.
puts previous_changes[:name][0]
end
end
u = User.first # => #<User id: 1, name: "Nimish Gupta">
u.update(name: 'Nimish Mahajan') # => this will fire both before_update and after_update callbacks.

希望这对你有帮助。

你也可以看看这个答案了解更多信息

我认为您在持久化对象上使用changed?attribute_waschanged?仅在对象脏的情况下有效。有关更多详细信息,请参阅https://api.rubyonrails.org/classes/ActiveModel/Dirty.html

class Todo < ApplicationRecord 
end
todo = Todo.new
todo.changed? # => false
todo.persisted? # => false

如果您将对象保存在DB中,则对象将持久化(不再存在脏数据(

todo = Todo.new(name: 'Test') 
todo.name_was # => nil
todo.name_changed? #=> true
todo.save
todo.persisted? # => true
todo.name_was # => Test
todo.name_changed? #=> false

最新更新