gpt4 book ai didi

ruby-on-rails - 如何检查内存中记录的数据库更改?

转载 作者:行者123 更新时间:2023-12-04 05:43:27 26 4
gpt4 key购买 nike

我想检查 ActiveRecord实例已按数据库更改。就像是:

p1 = Product.first
p1.name #=> "some name"

p2 = Product.first
p2.name = "other name"
p2.save #=> true

p1.database_changed? #=> true

我目前正在将记录的属性与持久属性进行比较:
class Product < ActiveRecord::Base

def database_changed?
Product.find(id).attributes != attributes
end

end

这似乎可行,但我想知道是否有内置方法来查找数据库更改?

最佳答案

之后Зелёный's comment我已查看 ActiveModel::Dirty并意识到它几乎可以满足我的要求。已经有一个内存状态(记录的属性)和一个数据库状态(由 ActiveModel::Dirty 处理)。我只需要一个方法来更新数据库状态,保持内存状态不变:

def refresh
@changed_attributes = {}
fresh_object = self.class.unscoped { self.class.find(id) }
fresh_object.attributes.each do |attr, orig_value|
@changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value, @attributes[attr])
end
self
end
  • @changed_attributesActiveModel::Dirty的散列来存储更改的值。我们显然必须重置它。
  • fresh_object是相同的记录,新从数据库中获取(this line 来自 reload,感谢 emaillenin)。
  • 在循环中,每个(新的)属性都与相应的(内存中的)属性进行比较。如果它们不同,则将其添加到 @changed_attributes哈希。 This line来自 ActiveRecorddup方法。 (它实际上来自 dup 调用的私有(private)方法,并且 _field_changed 也是私有(private)的。使用 ActiveRecord 的公共(public) API 可能会更好,但我很懒)
  • 最后,refresh返回 self为方便起见,就像 reload做。

  • 这是一个示例用法:
    p1 = Product.first
    p1.name #=> "some name"
    p1.changed? #=> false

    p2 = Product.first
    p2.name = "other name"
    p2.save #=> true

    p1.refresh
    p1.name #=> "some name"
    p1.changed? #=> true
    p1.name_changed? #=> true
    p1.name_was #=> "other name"

    p1.name = "other name"
    p1.name_changed? #=> false

    p1.changed? #=> true
    p1.changes #=> {"updated_at"=> [Tue, 29 Jul 2014 21:58:57 CEST +02:00, Tue, 29 Jul 2014 15:49:54 CEST +02:00]}

    关于ruby-on-rails - 如何检查内存中记录的数据库更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25012800/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com