On Mongomatic, Sinatra, Padrino, and Rails 3 Support
Note: This was originally posted on my previous blog. It is archived here for sentimental, educational (to me) and, in the unlikely case, actual value
If you have played with Mongomatic, by now you’ve probably started using it with your favorite Ruby web framework. Recently, I released sinatra-mongomatic and mongomatic-rails3, gems adding support for Sinatra and Rails, respectively. John Vincent, also, added Mongomatic support to Padrino and has, generously, contributed the related section in this post.
Singing Mongomatic with Sinatra
Requiring sinatra-mongomatic in your Sinatra application automatically requires everything you need to use Mongomatic. In addition, it adds the mongomatic helper method to configure your connection details. sinatra-mongomatic can be used with both classic and modular Sinatra styles.
Here is an example in the classic style:
require 'sinatra'
require 'sinatra/mongomatic'
# Usually in another file. Included here for brevity
class User < Mongomatic::Base
end
mongomatic Mongo::Connection.new.db("test2")
get '/create/:name' do
User.new(:name => params[:name]).insert
"ok"
end
Checkout the examples for more help.
Mongmatic and the Godfather
Written by John Vincent
In a nutshell, Padrino is a Ruby framework (similar to Rails in concept) built upon the Sinatra Microframework. Using Mongomatic in Padrino currently requires the version from Padrino’s github repository. The code has been accepted and will be in the upcoming 0.9.15 release. Don’t worry, the github master branch is very stable and is unit tested on each commit via Hudson. I’m going to assume you’re using RVM and have a gemset created for testing.
git clone http://github.com/padrino/padrino-framework.git
gem install bundler --pre
cd padrino-framework
bundle install
bundle check
bundle exec rake test # If you're paranoid
bundle exec rake package
bundle exec rake install
You should now be running the master branch. As with any other ORM supported in Padrino, usage is as simple as this:
padrino g project pblog -d mongomatic
cd pblog
bundle install
padrino g model post name:string body:text
Your database configuration will be in config/database.rb.Your generated model file will be in app/models/post.rb. The model file is heavily commented so take a look if you have any questions. Being true to the nature of MongoDB, Mongomatic doesn’t require you to define any model attributes for use. In the case of the Padrino driver, we’ve made some assumptions:
* Defining a column during model generation makes that a required value via
Mongomatic's Expectations Helper.
* Any attribute defined as an integer will additionally use Expectations to
ensure that data added is an integer.
You can interact with your model via the padrino console:
$ padrino console
=> Loading development console (Padrino v.0.9.14)
=> Located unlocked Gemfile for development
=> Loading Application Pblog
ruby-1.9.1-p378 >
At this point you can interact with your model using normal Mongomatic model methods:
ruby-1.9.1-p378 > Post.empty?
=> true
ruby-1.9.1-p378 > p = Post.new(:name => 'My first blog post')
=> #<Post:0x00000003bc7e30 @doc={"name"=>"My first blog post"}, @removed=false, ...>
ruby-1.9.1-p378 > p.valid?
=> false
ruby-1.9.1-p378 > p.errors
=> [["body cannot be blank"]]
ruby-1.9.1-p378 > p["body"] = <<EOT
ruby-1.9.1-p378"> Today I learned how to use Mongomatic with Padrino.
ruby-1.9.1-p378"> I'm much cooler than the other kids on the block now!
ruby-1.9.1-p378"> EOT
=> "Today I learned how to use Mongomatic with Padrino. I'm much cooler than...
ruby-1.9.1-p378 > p.valid?
=> true
ruby-1.9.1-p378 > p.insert
=> BSON::ObjectID('4c6fdf1579af411f57000001')
ruby-1.9.1-p378 > Post.empty?
=> false
ruby-1.9.1-p378 > Post.count
=> 1
ruby-1.9.1-p378 >
Staying true to the adhoc nature of MongoDB, I could add a new field to my record. The model is, however, unaware of this:
ruby-1.9.1-p378 > p["author"] = "padrinouser@example.com"
=> "padrinouser@example.com"
ruby-1.9.1-p378 > p.valid?
=> true
ruby-1.9.1-p378 > p.update
=> 273
ruby-1.9.1-p378 > p
=> #<Post:0x00000003bc7e30 @doc={"name"=>"My first blog post", "body"=>"Today I
learned how to use Mongomatic with Padrino. I'm much cooler than the other kids
on the block now!\n", "_id"=>BSON::ObjectID('4c6fdf1579af411f57000001'),
"author"=>"padrinouser@example.com"}, @removed=false, @is_new=false, @errors=[]>
Current limitations:
One nicety that Padrino provides is an ‘admin’ interface similar in concept to Django. Due to the design of Mongomatic, admin support is not available using the Mongomatic driver. Admin support is NOT required for any Padrino application so this limitation may not be an issue in your use case.
Future enhancements:
I’d like to add similar validation for each datatype of which the Padrino generator is aware as done with “integer”. Mongomatic work is being done in a branch of the lusis fork.
For more information check out John’s example application.
Riding Mongomatic with Rails 3
Mongomatic can be used, as provided from the core gem, with Rails 2 & 3. I, myself, and Ben Myles, Mongomatic’s creator, use only the Mongomatic gem in both Rails 2 & 3 applications in production. This is what we recommend. However, some Rails developers may be more accustomed to some of Rails’ niceties (I’m thinking helpers mostly here). Although the core of Mongomatic can still be used with many of these helpers, if you know what to give them, the mongomatic-rails3 gem makes it a bit easier for those so inclined and who are also using Rails 3. It also provides you with generators and config file support.
You can install Mongomatic and mongomatic-rails3 by simply adding the latter to your Gemfile:
gem 'mongomatic-rails3', :require => 'rails/mongomatic'
and running bundle install.
After installing you can generate your configuration file with:
rails g mongomatic:config [DB]
For more information on this generator you can run it with the –help option.
The config file is somewhat atypical. Its one commonality is that you still define connections for each environment. However, instead of having a verbose YAML file with many keys, you simply provide each environment with an instance of Mongo::DB. You can use ERB to make sharing common connection options simpler. The example below is what is generated if no database is given when you run the config generator.
development: Mongo::Connection.new.db("test")
test: Mongo::Connection.new.db("test")
production: Mongo::Connection.new.db("test")
mongomatic-rails3 fully implements the ActiveModel generator and sets it self as the application ORM. This means that when you run rails g model a subclass of Mongomatic::Base is generated. The generator currently doesn’t support the auto-generation of validation along with the model like Padrino. However, because I like what John has done support for this will come in a future version.
A Note on Scaffolds
mongomatic-rails3 adds support for Scaffold generation, however, scaffold support is currently limited. This library does not yet support form_for, due to its hash-only data access syntax (you should instead use form_tag), which scaffolds generate in their views (yet will most likely mean a special form helper for Mongomatic). You can, however, still use scaffolds as a starting point.