测试attribute_changed? VS. previous_changes检查特定属性是否更改(Rails),行为不同

时间:2018-05-26 04:52:31

标签: ruby-on-rails

除了文档指定的返回类型之外,我在after_save中测试了2个不同方法中以下两行之间的差异:

[:attribute_1, :attribute_2].any? {|a| self.send("#{a}_changed?")}

[:attribute_1, :attribute_2].any? {|attribute| self.previous_changes.key? attribute.to_s}

model.save!多次调用,但令我惊讶的是,当其中一个属性发生更改时,第一行返回true,但第二行返回false,而previous_changes是空哈希。有人可以解释为什么会发生这种情况吗?

Rails版本:'3.2.22.1'

1 个答案:

答案 0 :(得分:1)

保存模型后预先填充以前的更改(after_save回调是此过程的一部分)

如果您想要相同的行为,您可能正在寻找changes方法。使用它将返回您期望的结果。

根据ActiveModel::Dirty文档(它在Rails 3中具有相同的行为)

person = Person.new
person.name = 'Bob'
person.name_changed?  # => true
person.changes        # => {"name" => [nil, "Bill"]}
person.save

person.name_changed?     # => false
person.changes           # => {}
person.previous_changes  # => {"name" => [nil, "Bill"]}
person.reload!
person.previous_changes  # => {}

但是如果您尝试在after_commit回调中检查相同内容,则会得到不同的结果,因为在保存模型后会调用after_commit。因此,previous_changes将被预先填充,但changes将为空。