How to configure MongoMapper and ActiveRecord in same Ruby Rails Project
Asked Answered
B

2

7

I've got an existing production Ruby/Rails app that I want to migrate to MongoDB over time, as time permits, because it's not an option to just rewrite it all at one time. I'd love to be able to just deprecate my old classes as I get to them. I plan to use MongoMapper. I can't find an example where anyone explains how to set up the database config files to allow connection to both data stores within one app.

FWIW, I'm using Rails 3. I appreciate the help.

Belting answered 20/7, 2011 at 2:52 Comment(0)
E
6

Include your mongo_mapper gem in you Gemfile. Then in the models that you slowly want to start migrating over to MongoMapper, you just include this in your model:

include MongoMapper::Document

here is an example of a Mongo publisher model

class Publisher
  include MongoMapper::Document

  key :_id, String
  key :mtd_uniques, Integer
  key :mtd_demo_uniques, Integer
  key :archive, Array
  key :ignore, Boolean
end

My user model (postgres):

class User < ActiveRecord::Base
  validates_presence_of :first_name, :last_name, :email, :type
  acts_as_authentic

  def self.inherited(child)
    child.instance_eval do
      def model_name
        User.model_name
      end
    end
    super
  end
end

The nice thing about this is that all of your other models still use ActiveRecord so you can use 2 different databases till everything is migrated over to Mongo. This is an example from what I'm using. Large data aggregations using MongoMapper, and User model using postgres (app hosted on Heroku)

For my setup I dumped config stuff in my config.yml

development:
  adapter: MongoDB
  host: localhost
  database: my-dev-db

test:
  adapter: MongoDB
  host: localhost
  database: my-dev-db

staging:
  adapter: MongoDB
  host: remote-host (for me amazon ec2)
  database: my-staging-db

production:
  adapter: MongoDB
  host: remote-host (for me amazon ec2)
  database: my-production-db

and created an initializer that differentiates between the 2 DBs:

/initializers/database.rb

# load YAML and connect
database_yaml = YAML::load(File.read("#{Rails.root}/config/config.yml"))
puts "Initializing mongodb"
if database_yaml[Rails.env] && database_yaml[Rails.env]['adapter'] == 'MongoDB'
  mongo_database = database_yaml[Rails.env]
  MongoMapper.connection = Mongo::Connection.new(mongo_database['host'], 27017, :pool_size => 5, :timeout => 5)
  MongoMapper.database =  mongo_database['database']
end
Escapade answered 20/7, 2011 at 6:17 Comment(3)
Thanks @Chris. I had to make one minor change: File.read("#{Rails.root}/config/config.yml") After that, it just worked. Thanks so much for taking the time to answer this and making it so clear.Belting
Ah right! I had set RAILS_ROOT as a constant. Glad it worked out.Escapade
Hey Chris, glad you're playing with this. It turns out that in recent versions, the config and initializer parts are no longer needed. See my answer below.Disciplinary
D
2

It looks like that the initializer code from the previous answer is no longer needed. mongo_mapper will on its own look for a file config/mongo.yml and parse it and start the connection. Similar to ActiveRecord's database.yml or Mongoid's monogoid.yml.

Mongo mapper even ships with a Rails generator to set this file up for you. All you have to do is:

rails g mongo_mapper:config

This has resulted in:

defaults: &defaults
  host: 127.0.0.1
  port: 27017

development:
  <<: *defaults
  database: db_name_development
...

Of course it would be nice if they mentioned this in the Readme or on the doc site. I'm using mongo_mapper version 0.10.1

Disciplinary answered 4/1, 2012 at 4:53 Comment(1)
Agreed. This post is kinda old. Right now we are using MongoDB for our analytics but aren't even using MongoMapper. I think it's best to just use the mongo ruby driver (github.com/mongodb/mongo-ruby-driver) and just craft your custom integration points needed by the app. No need to fool ActiveRecord into thinking that mongo documents are AR objects.Escapade

© 2022 - 2024 — McMap. All rights reserved.