【问题标题】:Understanding "attribute_will_change!" method了解“attribute_will_change!”方法
【发布时间】:2014-07-20 10:11:15
【问题描述】:

我想覆盖store_accessor 的getter。可以找到here。代码在这里:

# File activerecord/lib/active_record/store.rb, line 74
      def store_accessor(store_attribute, *keys)
        keys = keys.flatten

        _store_accessors_module.module_eval do
          keys.each do |key|
            define_method("#{key}=") do |value|
              write_store_attribute(store_attribute, key, value)
            end

            define_method(key) do
              read_store_attribute(store_attribute, key)
            end
          end
        end

        self.stored_attributes[store_attribute] ||= []
        self.stored_attributes[store_attribute] |= keys
      end

我实现了我想要的功能,但是如果我还要覆盖 setter,有一个我不清楚的方法,它在 write_store_attribute(...) 方法中(找到 here)。

代码在这里:

# File activerecord/lib/active_record/store.rb, line 108
      def write_store_attribute(store_attribute, key, value)
        attribute = initialize_store_attribute(store_attribute)
        if value != attribute[key]
          send :"#{store_attribute}_will_change!"
          attribute[key] = value
        end
      end

我不明白的方法是"#{whatever_store_att}_will_change!"

如果我要覆盖 setter,我会使用 update_attributesupdate_column。这种赋值attribute[key]=value的方法是否实际上修改了数据库中的字段,使其等效于update_attributes

【问题讨论】:

    标签: ruby-on-rails ruby postgresql activerecord hstore


    【解决方案1】:

    这是 activemodel 更改跟踪系统的一部分,活动记录使用它来了解它需要写入数据库的内容(如果有的话)。

    当您对记录调用 save 时,activerecord 会为它认为已更改的所有属性创建一个更新查询(如果没有更改的属性,则它什么也不做)。

    activerecord 为您生成的访问器会自动为您处理此问题,但在某些情况下,它有助于告诉 activerecord 属性是脏的并且需要更改(例如,如果您更新某些内容,绕过通常的更改跟踪机制) .

    这正是这里发生的情况:当您为存储的属性设置键时 - rails 会修改散列(而不是分配新的散列),因此需要调用 _will_change! 来通知更改跟踪下一次调用 save 时,底层属性将需要写入数据库。

    【讨论】:

    • 谢谢!很好的解释。几个问题:1) 查看 Rails 3.2.13 而不是 Rails 4.x 的同一文件,我可以看到对 _will_change! 的调用已完成分配attribute[key]=value之后,不像Rails 4。我想这没关系? 2) 我猜这是Hstore 列的事实不相关,对吧?因为在早期版本的 Rails 中,不可能为 hstore 列创建访问器。还是我弄错了?
    • 应该没什么区别。我不认为 hstore 的东西很重要——它与 rails 一直以来的序列化列没有太大区别,除了(至关重要的)数据库理解序列化
    猜你喜欢
    • 2016-07-06
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    • 2014-09-13
    相关资源
    最近更新 更多