问题
This is very similar to Rails partial updates problem with hashes , but the question has not really been answered IMHO.
The problem is this: I have a model with a serialized column:
class Import < AR::Base
serialize :data
In my case, this data will, and should, not change after the first save/creation of the model. So I want to disable the feature of AR that always saves serialized columns (which is normally a good idea, as it can't detect those changes). I want to disable the saving because the data can be quite large, and the model will be updated frequently.
I've already tried monkeypatching into ActiceRecord::AttributeMethods::Dirty like this:
class Import
def update(*)
if partial_updates?
super(changed | (attributes.keys & (self.class.serialized_attributes.keys - ["data"])))
else
super
end
end
but this seems to have no effect. Anybody got a better idea ?
This is under Rails 3.0.12
回答1:
What I ended up doing, even though it's not really an answer to the original question, is the following:
class Import < AR::Base
belongs_to :storage
class Storage < AR::Base
serialize :data
...i.e. moving the data column into a model of its own, and associate that with the original model. Which is actually conceptually somewhat cleaner.
回答2:
Here is an ugly monkey patch solution:
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
You will have to remember to call cache_spam!, or your serialized attribute will never be saved.
来源:https://stackoverflow.com/questions/9981257/stop-activerecord-saving-a-serialized-column-even-if-not-changed