Using Mongo And Mongoid Without Rails
In my previous post on writing a thor application, I mentioned the use of mongo db and the mongoid document mapper, and how I am using these tools outside the context of a rails application. As I mentioned in that post, it’s turned out to a fairly simple thing to do. I was surprised at how easy it was to get set up, configure and use, honestly.
Bundling Mongoid With My App
I use bundler and RVM together, to organize and manager my ruby versions and gems for my applications. It’s a powerful little combination and makes the setup and configuration of Mongoid really simple. Here’s the contents of the Gemfile for the application that I showed in my post on writing a thor app:
gem 'mongoid', '2.0.1'
gem 'ruby-hl7', '1.0.3'
gem 'thor', '0.14.6'
gem 'bson_ext', '1.3.0'
gem 'whenever', '0.6.7'
gem 'rake', '0.8.7'
gem 'vlad', '2.2.0'
gem 'vlad-git', '2.2.0'
It’s a fairly simple Gemfile, but even with such a small number of gems, it’s important to keep everything organized and on the right versions. Therefore, the use of a Gemfile is nearly essential to any ruby application – rails or not. Run ‘bundle install’ with this Gemfile in place, and everything I need is installed – including the mongoid gem.
Command Line vs YAML Configuration
Once mongoid is installed, you have a few options for configuring it, according to the documentation. You can either load up the configuration via a yaml file, or call `Mongoid.configure` to set things up.
The first pass I made at this was using a yaml file. I started by copying a mongoid.yml file out of a rails app, but that failed miserably. Apparently, the mongoid rails integration does some magic to handle a structured yml file with many different environments in it. However, with v1.x of mongoid, the standard .load! method does not parse an environment section. Perhaps v2.x does, but I haven’t had a chance to upgrade and try it, yet.
In the end, I went with the code configuration of Mongoid. This was done partially because I didn’t want a bunch of yml files around, and partially so that I could figure out the best way to supply the configuration from the environment that is running the application, at deploy time, or whenever (but that’s another post.)
I also didn’t use the code that was supplied in the documentation. Honestly, that code is a little lacking – it does nothing more than show you how to connect to a database. It doesn’t do anything to show you how to connect with a username and password, a server name and port, or anything else. Fortunately, Robin Mayfield has a great little post with a nice little update at the bottom, showing an easy way to do all of this. I took his code and modified it to work with the optional command line parameters of my thor script, allowing no configuration to be passed in (which defaults the server to localhost and the database to my development database) or the options of username, password, server, database name, and port # to be passed in. The end result looks like this:
Mongoid.database = Mongo::Connection.new(options.server).db(options.database) if options.user Mongoid.database.authenticate(options.user, options.password) end
The options class comes from my post on building a thor application. This is the OpenStruct that I created out of the options hash that thor created for me. Also note that I’m never checking or defaulting the server and database values in this code, directly. I’m letting thor do that for my by using the :default => “value” option for the method_options in question.
These few lines of code are all I needed to configure mongoid in my little app, in combination with the options that the thor script provides.
Model As If It Were A Rails App
From here, I’m able to model and use my models as if I were writing a rails app with mongoid. Creating a mongoid document is as simple as
field :a_date, :type => DateTime
And I now have all the persistence that I need for my model, including the embedded that_model document. Of course, my models are no where near this simple. I’ve got a fair amount of business logic in most of them, multiple models to represent the hierarchy of data and process that my app needs, etc. However, I did not have to do anything special or learn anything new to build my models outside of the rails app. It was only the configuration of mongoid that needed anything different… yet another reason that I love mongoid. It’s just a pleasure to work with, most of the time.