【问题标题】:rails 3 - where to put app startup initialization stuff?rails 3 - 在哪里放置应用程序启动初始化的东西?
【发布时间】:2011-03-10 11:34:50
【问题描述】:

在我的应用程序(jruby、rails 3、mongodb)中,我在初始化程序 /config/initializers/app_constants.rb 中设置了我的数据访问对象(和其他“单例”)

DATA_COLLECTION_STORE = DataCollectionStore.new(...)

SOME_OTHER_SINGLETON = SomeOtherClassTreatedLikeSingleton.new(...)

我是 Rails(和 ruby​​)的新手,我意识到了一些事情。首先,设置这些“单例”一定不是正确的方法,因为这些类可以在代码中的任何其他位置随时实例化(目前假设不会发生)。其次,当我尝试运行测试(rake 规范)或构建 WAR(使用 warble)时,将这些“常量”放在这个初始化程序中似乎是错误的 b/c 我可以看到初始化程序的东西正在运行,所以我正在创建与 mongo 的连接,开始我的“some_other_singleton”等

这种东西应该去哪里?

提前感谢您对我的菜鸟的耐心:)

【问题讨论】:

    标签: ruby ruby-on-rails-3


    【解决方案1】:

    您不需要在任何配置文件中实际初始化您的单例。 相反,您可以在您的类中实现一个将返回单例的类方法。以下代码将允许您使用 DataCollectionStore.instance 访问单例

    class DataCollectionStore
      @@instance = DataCollectionStore.new
    
      def self.instance
        @@instance
      end
    
      def initialize
        #intitialize you instance here
      end
    
    end
    

    请记住,您必须在 development.rb 中将 config.cache_classes 设置为 true 才能在您的开发环境中工作。不过,默认情况下,类在生产中被缓存。

    或者,您可以将类本身用作单例对象并在类方法中实现您的功能。

    如果你的初始化很昂贵,你可以使用下面的 sn-p 懒惰地进行。这样,只有在您的测试实际调用实例类方法时,您才需要付出代价。 您可以通过在视图中输出DataCollectionStore.instance 并使用不同的浏览器加载页面来在您的应用程序中对此进行测试。如果一切正常,您应该会在两个浏览器中看到相同的时间戳。

    class DataCollectionStore
      @@instance = nil
    
      def self.instance
        @@instance || @@instance = self.new
      end
    
      def initialize
        @initialized_time = Time.now
      end
    
      def to_s
        @initialized_time
      end
    end
    

    【讨论】:

    • 感谢您的想法。但是在“初始化程序”中设置/启动东西的另一个问题呢?要运行一个简单的 RSpec 控制器测试,它需要将近 50 秒,因为它首先执行那些导致我的应用程序创建与数据库的连接、加载一些数据和其他内容的初始化程序。
    • 你可以让实例类方法懒惰地创建任何昂贵的资源。这样,只有在您的测试确实需要调用实例方法时,您才会受到影响。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 2019-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    相关资源
    最近更新 更多