Stop ActiveRecord while maintaining a serialized column, even if it is not modified

This is very similar to the problem of partially updating Rails with hashes , but IMHO did not actually answer this question.

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 / create model. So I want to disable the AR function, which always saves serialized columns (which is usually a good idea since it cannot detect these changes). I want to disable saving because the data can be quite large and the model will be updated frequently.

I already tried monkeypatching in 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 does not seem to have any effect. Has anyone got a better idea?

This is under Rails 3.0.12

+6
source share
2 answers

What I finished, even if this is not the answer to the original question, is as follows:

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

... i.e. moving the data column to your own model and matching it with the original model. Which is actually conceptually somewhat cleaner.

+6
source

Here is an ugly solution to fix a monkey:

 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.

+3
source

Source: https://habr.com/ru/post/912250/


All Articles