即使未更改,也要停止ActiveRecord保存序列化列
这与散列的Rails部分更新问题非常相似,但问题并没有真正得到回答恕我直言。
问题是这样的:我有一个带序列化列的模型:
class Import < AR::Base serialize :data
就我而言,在第一次保存/创建模型后,这些数据将会,而且应该不会更改。 所以我想禁用AR的function,它始终保存序列化列(这通常是一个好主意,因为它无法检测到这些更改)。 我想禁用保存,因为数据可能非常大,模型会经常更新。
我已经尝试过monkeypatching到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下
我最终做了什么,即使它不是对原始问题的真正答案,如下:
class Import < AR::Base belongs_to :storage class Storage < AR::Base serialize :data
...即将数据列移动到自己的模型中,并将其与原始模型相关联。 实际上这在概念上有点清洁。
这是一个丑陋的猴子补丁解决方案:
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!,否则您的序列化属性将永远不会被保存。