How to change db connection on the fly in a rails app.

1,934 views
Skip to first unread message

antlypls

unread,
Oct 12, 2011, 8:00:13 AM10/12/11
to Mongoid
Hey!

I'm using mongoid 2.2.3 in rails 3.0.10 app.
I've encountered in situation where i need to use multiple mongodb
databases in certain cases.
So I need to be able to switch db settings (different than in
config.yml) during request processing.
In my case it seems that the best place to do this is before_filter in
application controller.

I've found that following code allows to change db for same server^

class ApplicationController < ActionController::Base
before_filter :set_database

def set_database
Mongoid.master.connection.close
Mongoid.database = Mongoid.master.connection.db(db_name)
Mongoid.master.connection.connect
end
end

Is it good solution?

Another question is what is best solution to change whole connection
settings on the fly: host, port, db name?

Durran Jordan

unread,
Oct 13, 2011, 4:34:42 AM10/13/11
to mon...@googlegroups.com
That's probably the best way at the moment, but in 3.0.0 I'm going to change the internals to handle this on the fly with ease:

https://github.com/mongoid/mongoid/issues/1291

As for changing the entire connection, you could do it via:

Mongoid.master = Mongo::Connection.new.db("my_other_db_name")

2011/10/12 antlypls <antl...@gmail.com>

Durran Jordan

unread,
Feb 21, 2013, 10:45:36 AM2/21/13
to mon...@googlegroups.com
There are a myriad of ways now, but the most common is using #with:

Model.with(database: "other_db_name").create (works with any persistence call: create!, save, delete, etc)

See: http://mongoid.org/en/mongoid/docs/persistence.html#custom

2013/2/19 <louis....@gmail.com>
Hey Durran, has this been implemented in the end? What's the API for doing this?

Thanks,
Louis

--
 
---
You received this message because you are subscribed to the Google Groups "Mongoid" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongoid+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Jon

unread,
Jun 21, 2013, 4:12:50 PM6/21/13
to mon...@googlegroups.com
Hey Durran,

Is there a good way to do this in Mongoid 3 now that Mongoid.master= doesn't exist? We're tossing around the idea of completely partitioning clients in different databases, and updating the thousands of Model.where() or update calls to use Model.with(:session => SessionFactory.get_session_for_client()) isn't practical.

Something like a before filter might as antlypls originally suggested might be one way to approach it.

Jon

Roman Gaufman

unread,
Mar 20, 2014, 6:55:37 AM3/20/14
to mon...@googlegroups.com
We have a multi tenant app and we're doing this in a before_filter in our ApplicationController:

Mongoid.override_database("#{database_name}")

And this in our after_filter:

Mongoid.override_database(nil)

Works great :)

Jonathan Hyman

unread,
Mar 20, 2014, 8:51:11 AM3/20/14
to mon...@googlegroups.com
Thanks. We ended up writing an abstraction using thread-local storage, it works like the example on mongoid.org.


--

---
You received this message because you are subscribed to a topic in the Google Groups "Mongoid" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mongoid/Rp64Tvjwtbk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mongoid+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Steve Schlotter

unread,
May 28, 2014, 8:41:43 PM5/28/14
to mon...@googlegroups.com
Roman,
I'm curious how this works.  
Does the user get directed to their database when they login using the database_name stored in their user record?  
And multiple users can be logged in and be using different databases simultaneously? 

Steve

Steve Schlotter

unread,
May 28, 2014, 9:02:44 PM5/28/14
to mon...@googlegroups.com
Jon,
Are you referring to the example here? http://mongoid.org/en/mongoid/docs/persistence.html#custom

Jonathan Hyman

unread,
May 28, 2014, 9:08:02 PM5/28/14
to mon...@googlegroups.com
Yeah, we use something like this pseudocode

store_in :session => lambda do
  Thread.current[:model_session_name] or raise StandardError.new("No session name defined")
end

This way, we catch all the places in code where we don't have something set.

Roman Gaufman

unread,
May 29, 2014, 4:49:49 AM5/29/14
to mon...@googlegroups.com
We do this from request.subdomain, each subdomain is a separate database


--

---
You received this message because you are subscribed to a topic in the Google Groups "Mongoid" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mongoid/Rp64Tvjwtbk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mongoid+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages