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