2012-04-02 17 views
6

यह बहुत Rails partial updates problem with hashes के समान है बदल गया है, लेकिन सवाल वास्तव में IMHO नहीं उत्तर दिया गया है बचत।बंद करो ActiveRecord एक धारावाहिक स्तंभ नहीं है, भले ही

समस्या यह है: मैं एक धारावाहिक स्तंभ के साथ एक मॉडल है:

class Import < AR::Base 
    serialize :data 

मेरे मामले में, इस डेटा, और पहले के बाद मॉडल के निर्माण को बचाने/परिवर्तन नहीं होना चाहिए होगा। तो मैं एआर की सुविधा को अक्षम करना चाहता हूं जो हमेशा सीरियलाइज्ड कॉलम सहेजता है (जो आम तौर पर एक अच्छा विचार है, क्योंकि यह उन परिवर्तनों का पता नहीं लगा सकता है)। मैं बचत को अक्षम करना चाहता हूं क्योंकि डेटा काफी बड़ा हो सकता है, और मॉडल को अक्सर अपडेट किया जाएगा।

मैं पहले से ही ActiceRecord :: AttributeMethods :: इस तरह गंदा में monkeypatching की कोशिश की है:

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

लेकिन इस पर कोई असर नहीं हो रहा है। किसी को भी बेहतर विचार मिला?

इस रेल 3.0.12

उत्तर

6

क्या मैं कर रहा समाप्त हो गया किया जा रहा है, भले ही यह वास्तव में मूल प्रश्न का उत्तर नहीं है, निम्नलिखित है:

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 !, या अपने धारावाहिक विशेषता बचाया जा कभी नहीं होगा याद करना होगा:

+0

यह वास्तव में भावना का एक बहुत, अंतर्दृष्टि साझा करने के लिए धन्यवाद बनाता है। मुझे लगता है कि मैं एक ही रास्ते पर जा रहा हूं, और _Storage_ मॉडल और अन्य के बीच एक पॉलिमॉर्फिक एसोसिएशन का उपयोग करता हूं जिसमें केवल-पढ़ने वाले क्रमबद्ध कॉलम हैं –

3

यहाँ एक बदसूरत बंदर पैच समाधान है।