codecraig
codecraig

Reputation: 3158

rails 3 - where to put app startup initialization stuff?

In my app (jruby, rails 3, mongodb) I setup my data access objects (and other 'singletons') in an initializer /config/initializers/app_constants.rb

DATA_COLLECTION_STORE = DataCollectionStore.new(...)

SOME_OTHER_SINGLETON = SomeOtherClassTreatedLikeSingleton.new(...)

I'm new to rails (and ruby) and I realize a couple things. First, setting up these "singletons" must not be the correct approach, since those classes can be instantiated at any time anywhere else in the code (for now it's assumed that won't happen). Secondly, putting these "constants" in this initializer seems wrong b/c when I try to run tests (rake spec) or build a WAR (using warble) I can see that the initializer stuff is running so I'm creating connections to mongo, starting my "some_other_singleton", etc.

Where should this sort of stuff go?

thanks in advance for being patient with my noobness :)

Upvotes: 1

Views: 2406

Answers (1)

Alternegro
Alternegro

Reputation: 809

You don't need to actually initialize your singletons in any config file. Instead, you can just implement a class method in your class that will return a singleton. The following code will allow u to access the singleton using DataCollectionStore.instance

class DataCollectionStore
  @@instance = DataCollectionStore.new

  def self.instance
    @@instance
  end

  def initialize
    #intitialize you instance here
  end

end

Keep in mind that you will have to set config.cache_classes to true in development.rb for this to work in your development environment. Classes are cached by default in production though.

Alternatively, you could just use the class itself as a singleton object and implement your functionality in class methods.

If your initialization is expensive, you can do it lazily using the snippet below. That way you only pay the price if your test actually invokes the instance class method. You can test this in your app by outputting DataCollectionStore.instance in a view and using different browsers to load the page. If every thing works right, you should see the same timestamp in both browsers.

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

Upvotes: 2

Related Questions