【问题标题】:Stop ActiveRecord saving a serialized column even if not changed即使未更改,也停止 ActiveRecord 保存序列化列
【发布时间】:2012-04-16 09:33:39
【问题描述】:

这与Rails partial updates problem with hashes 非常相似,但恕我直言,这个问题并没有真正得到回答。

问题是这样的:我有一个带有序列化列的模型:

class Import < AR::Base
  serialize :data

在我的情况下,这些数据在第一次保存/创建模型后不会而且应该不会改变。所以我想禁用始终保存序列化列的 AR 功能(这通常是个好主意,因为它无法检测到这些更改)。我想禁用保存,因为数据可能很大,而且模型会经常更新。

我已经尝试过像这样对 ActiceRecord::AttributeMethods::Dirty 进行猴子修补:

class Import
  def update(*)
    if partial_updates?
      super(changed | (attributes.keys & (self.class.serialized_attributes.keys - ["data"])))
    else
     super
   end
 end

但这似乎没有效果。有人有更好的主意吗?

这是在 Rails 3.0.12 下

【问题讨论】:

    标签: ruby-on-rails activerecord serialization partial updates


    【解决方案1】:

    我最终做了以下事情,尽管这并不是对原始问题的真正答案:

    class Import < AR::Base
      belongs_to :storage
    
    class Storage < AR::Base
      serialize :data
    

    ...即将数据列移动到自己的模型中,并将其与原始模型相关联。这实际上在概念上更干净。

    【讨论】:

    • 这实际上很有意义,感谢您分享见解。我想我会走同样的路,并在 Storage 模型和其他具有只读序列化列的模型之间使用多态关联
    【解决方案2】:

    这是一个丑陋的猴子补丁解决方案:

    module ActiveRecord
      module AttributeMethods
        module Dirty
          def update(*)
            if partial_updates?
              # Serialized attributes should always be written in case they've been
              # changed in place.  Unless it is 'spam', which is expensive to calculate.
              super(changed | (attributes.keys & self.class.serialized_attributes.keys - ['spam']))
            else
              super
            end
          end
          private :update
        end
      end
    end
    class Foo < ActiveRecord::Base
      serialize :bar
      serialize :spam
    
    
      def calculate_spam
        # really expensive code
      end
    
      def cache_spam!
        calculated_spam = calculate_spam
        @changed_attributes['spam'] = [spam, calculated_spam]
        self.update_attribute(:spam, calculated_spam)
      end
    end
    

    您必须记住调用 cache_spam!,否则您的序列化属性将永远不会被保存。

    【讨论】:

      猜你喜欢
      • 2012-11-12
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-10
      • 1970-01-01
      • 2015-02-12
      相关资源
      最近更新 更多