Ruby‎ > ‎Databases‎ > ‎

MongoDB

There are a couple ways to configure access to MongoDB. Presumably you're using mapping gems such as Mongoid orMongoMapper to handle the interface.

A simple and easy way is to set all the variables directly within your worker -- in an init method for example.

A more advanced way to do it is via the config setup within your application and then apply the settings as part of the worker initialization. This way lets you point to different databases depending on your environment (i.e. development or production).

Blog Article on Connecting to Mongo

First we should point out a great article by Daniel Kunnath from GameAttain on MongoDB/Mongoid integration with SimpleWorker.

MongoDB/Mongoid Integration with SimpleWorker

MongoDB Worker Example

Second, take a look at the MongoDB example on GitHub. It uses MongoHQ but will just as easily with self-managed MongoDB.

SimpleWorker Examples

Configuring Basic Access in the Worker

Once the configuration in place, you'd then read, write, and access the database as you would if your code is running locally.

The basic approach is to explicitly set the variables in the Worker class. You might, for example, create aninit_mongodb method to sets the keys and then call it in the run method of the worker.

class SomeMongoWorker < SimpleWorker::Base

  attr_accessor :mongo_host, :mongo_port, :mongo_db_name, :mongo_username, :mongo_password

  def run

    init_mongodb

    # Perform worker logic here

  end

  # Configures db settings.
  # (The setting here are variables but could just as easily be the explicit values.)

  def init_mongodb

    Mongoid.configure do |config|
      config.database = Mongo::Connection.new(mongo_host, mongo_port).db(mongo_db_name)
      config.database.authenticate(mongo_username, mongo_password)
      config.persist_in_safe_mode = false
    end
  end

end


For example, if you had a class called Person

class Person
  include Mongoid::Document
  field :first_name
  field :last_name
end

You'd reference it in your worker just as you would in your application.

...
person = Person.new(:first_name => "Ludwig", :last_name => "Beethoven the #{rand(100)}")
person.save!
...

Setting Up Global Attributes

A easiest way to pass in your database configuration if you're going to use it on several workers is to set global attributes which might change based on your environment.

In a Rails environment files, you'd set them like this:

SimpleWorker.config do |config|
  config.access_key = 'YOUR_ACCESS_KEY'
  config.secret_key = 'YOUR_SECRET_KEY'
  config.global_attributes[:mongodb_settings] = DATABASE[Rails.env]
end

In your worker, add another attribute called :mongodb_settings and  init_mongodb would then look like this.

def init_mongodb

  Mongoid.configure do |config|
    config.from_hash(mongodb_settings)
  end

end

Configure Database before Initializing Models

One important point is that in Rails, you need to configure the database before initializing the model. Otherwise, you run the risk of a "Database should be a Mongo::DB, not NilClass" error.

StackOverflow Issue: Mongoid With Rails Database

Passing DB Config Info in via Worker attr_accessors

You can also pass in db config settings within the worker data payloads. Again, you can either set them directly or read them from a config.yml or other type of file.

In the code that instantiates and queues the worker, you'd have this.

mw = SomeMongoWorker.new
mw.mongo_db_name   = "simpleworkertest"
mw.mongo_host   = "flame.mongohq.com"
mw.mongo_port   = 27080
mw.mongo_username = "USERNAME"
mw.mongo_password = "PASSWORD"

mw.queue

In your worker, you'd have the following with the run and init_mongodb looking like the first example above. (Not all the values need to be passed through. Persistent ones could be set directly.)

class SomeMongoWorker < SimpleWorker::Base

  attr_accessor :mongo_db_name, :mongo_host, :mongo_port, 
                            :mongo_username, :mongo_password

  ...

end

Other Resources

Here are some other resources on MongoDB:

Comments