2011-03-08 84 views
1

在發展中,我試圖通過包括ActiveRecord::Base類中的方法,使他們能夠配置的車型,它會給我一個鉤到模型添加到全局陣列收集我的應用程序中的所有車型。Rails的引擎不緩存

module EngineName 
    module ActiveRecordExtensions 
    extend ActiveSupport::Concern 

    included do 
     def self.inherited(klass) #:nodoc: 
     klass.class_eval do 
      def self.config_block(&block) 
      abstract_model = EngineName::AbstractModel.new(self) 
      abstract_model.instance_eval(&block) if block 

      EngineName::Models.add(abstract_model) 
      end 
     end 
     end 
    end 
    end 
end 

我的EngineName::Models類只是一個包裝所有模型的包裝。

module EngineName 
    class Models 
    class << self 
     def all 
     @models ||= [] 
     end 
     alias_method :models, :all 

     def navigation 
     @models - excluded_navigation_models 
     end 

     def routed 
     @models - excluded_route_models 
     end 

     # Creates an array of models if none exists. Appends new models 
     # if the instance variable already exists. 
     def register(klass) 
     if @models.nil? 
      @models = [klass] 
     else 
      @models << klass unless @models.include?(klass) || excluded_models.include?(klass) 
     end 
     end 
     alias_method :add, :register 
    end 
    end 
end 

在每個刷新雖然,我的模型內的config_block方法被調用並依次唱完我追加全球的車型陣列中相同的模型。

正如你可以看到下面了,每當我通過我的所有車型環,它將繼續追加本身。

enter image description here

有什麼辦法,以我的引擎內的緩存某些類型的?或者在我的模型中使用鉤子註冊模型的方法中是否存在缺陷?

回答

2

的問題是,在開發環境中您的模型得到重新加載在每次請求,以便更改這些類生效,你不必每次進行更改源代碼的時間重新啓動服務器。您可以在控制檯中看到此行爲:

User.object_id 
=> 2203143360 
reload! 
=> true 
User.object_id 
=> 2212653160 

這意味着,當你調用@models.include?(klass)你實際上是從上一個請求檢查您當前對一個對象實例。你會注意到,隨着時間的推移,你的內存會變得臃腫,因爲這些對象不會被刪除 - 因爲垃圾收集會因爲在你的@models實例變量中引用它們而使它們保留在周圍。這不會成爲生產中的問題,因爲類只加載一次,但會導致開發中的問題。

爲了解決這個問題,我會建議做這樣的事情:

module EngineName 
    class Models 
    class << self 
     def all 
     @models ||= {} 
     end 
     alias_method :models, :all 

     def register(klass) 
     if @models.nil? 
      @models = {klass.name => klass} 
     else 
      @models[klass.name] = klass unless excluded_models.keys.include?(klass.name) 
     end 
     end 
     alias_method :add, :register 
    end 
    end 
end 

使用散列函數將讓您跟蹤模型由他們的名字,每當一個模型的新版本來自各地將取代舊的過時版本。這應該有助於您的開發環境。要獲得所有型號的清單,您只需使用@models.values並獲取型號名稱列表,您只需使用@models.keys

+0

我會試試這個,讓你知道它是怎麼回事,謝謝!我會把它標記爲正確的,但我想先試試它......如果你不介意的話:) – Garrett 2011-03-08 19:34:08

+0

這個工程,感覺更合乎邏輯...允許我把它分解以及incase我只想要一些模型在某些地方。再次感謝! – Garrett 2011-03-08 19:49:30