Hey everyone! I have a problem that''s been making me a little nuts. I would like to use RoR for a upcoming project, but if I can''t get past this hiccup I''m afraid I''ll have to use PHP or Java. Ugh. The application needs to have a database-per-customer model. So when I do a Product.find(:all) I need to make sure i''m connecting to say acme.products and not xyz_company.products. I toyed around with the magic_multi_connections gem but I''m having trouble getting it to work without knowing the connection up front. In the examples it shows how to connect when you know which db you''ll need ... in their example :Private. I attempted to look at the code, but there is some meta programming stuff in there that is beyond my newb level i''m afraid. The other problem with the magic_multi is that if there are 140 customers then I need 140 modules added in the environment.rb. That doesn''t sound fun! If anyone has done something like that and can''t get me started I''d be so grateful! And please, if I wasn''t clear enough, ask me to elaborate rather than ignoring the post. I only have a couple more days to decide which language to use, and i''d really like to go with Ruby and Rails.
jmamma wrote:> Hey everyone! I have a problem that''s been making me a little nuts. > I would like to use RoR for a upcoming project, but if I can''t get > past this hiccup I''m > afraid I''ll have to use PHP or Java. Ugh.check out data_fabric gem http://www.codefutures.com/database-sharding/ and check this article -- Posted via http://www.ruby-forum.com/.
Thanks Amar. Sharding isn''t exactly what I need here, but some interesting info nonetheless. I have a main db ( users, applications, etc ) and a database for each customer ( products, orders, etc ) When I want to get all the products, for example, I need to connect to a particular customers version of products. I can do it by using ActiveRecord::Base.establish_connection (:connection_name) in the controller but its not perfect... also there are some plugins that use some activeRecord stuff in them and the model doesn''t know which db its supposed to connect to so I have to modify all those gems and put the establish_connection in there too. I put the customer in session on user login, and then I can easily get which customer db I need, but again that doesn''t work so well in the models since the session isn''t easily available in the models. On Nov 2, 7:12 am, Amar Daxini <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> jmamma wrote: > > Hey everyone! I have a problem that''s been making me a little nuts. > > I would like to use RoR for a upcoming project, but if I can''t get > > past this hiccup I''m > > afraid I''ll have to use PHP or Java. Ugh. > > check out data_fabric gemhttp://www.codefutures.com/database-sharding/and check this article > -- > Posted viahttp://www.ruby-forum.com/.
jmamma wrote:> Hey everyone! I have a problem that''s been making me a little nuts. > I would like to use RoR for a upcoming project, but if I can''t get > past this hiccup I''m > afraid I''ll have to use PHP or Java. Ugh. > > The application needs to have a database-per-customer model.[...] Why does it "need" to have a database per customer? There''s usually no reason for that sort of thing. In most cases, you really just want one big DB. Can you explain more about what''s going on? Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/.
The usual trick in situations like this is to use a thread-local variable, set in the controller action and accessed from the models. It''s a somewhat leaky abstraction, but probably the most reliable way to do things (ActiveSupport uses it for the Time.zone stuff). The code would look like (sketch): in application_controller.rb (or elsewhere): before_filter :set_customer_db def set_customer_db Thread.current[:customer_db] = ... end I can''t think of how exactly you''ll end up accessing it in the models, but the magic_multi_connections gem should provide some guidance. --Matt Jones On Nov 2, 8:09 am, jmamma <jackli...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Thanks Amar. Sharding isn''t exactly what I need here, but some > interesting info nonetheless. > > I have a main db ( users, applications, etc ) and a database for each > customer ( products, orders, etc ) > > When I want to get all the products, for example, I need to connect > to > a particular customers version of products. I can do it by using > ActiveRecord::Base.establish_connection (:connection_name) in the > controller > but its not perfect... also there are some plugins that use some > activeRecord > stuff in them and the model doesn''t know which db its supposed to > connect to > so I have to modify all those gems and put the establish_connection in > there too. > > I put the customer in session on user login, and then I can easily get > which customer > db I need, but again that doesn''t work so well in the models since the > session isn''t > easily available in the models. > > On Nov 2, 7:12 am, Amar Daxini <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > wrote: > > > > > jmamma wrote: > > > Hey everyone! I have a problem that''s been making me a little nuts. > > > I would like to use RoR for a upcoming project, but if I can''t get > > > past this hiccup I''m > > > afraid I''ll have to use PHP or Java. Ugh. > > > check out data_fabric gemhttp://www.codefutures.com/database-sharding/andcheck this article > > -- > > Posted viahttp://www.ruby-forum.com/.
Thanks for your suggestion Matt. I''ll look into it a bit and see if it will work. I''m not stuck on using the magic_multi_connections at this point. I''d go with an easier way if I could figure it out. I tinkered with just having a method in the application_controller that sets the connection via establish_connection ( from a value in session ), and it seems to work okay. Its just a little clunky in a few parts and it doesn''t solve the problem when you need to make a db call in the model ( or some plugin tries to use a model find(:all) or something ). Marnen - We need a db per customer for a few reasons. It will keep the clients data separate ( some of them are weird like that about their data, and require us to separate ), and also a particular customer could have a customer feature they purchase that won''t make sense for all clients. That feature will cause for extra tables or columns in that particular customers db that won''t be spread to everyone. Also, this way we can easily backup a particular customer, or grab a customer''s db a dump it on our local machine really quick and test with their data, rather than pulling down a giant db. And finally, we can take down a particular customer rather easy and not affect anyone else. I''m in some ways trying to convince myself that its a good thing to do as well, since I don''t have much choice in the matter haha! Thanks for the input though! On Nov 2, 12:24 pm, Matt Jones <al2o...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> The usual trick in situations like this is to use a thread-local > variable, set in the controller action and accessed from the models. > It''s a somewhat leaky abstraction, but probably the most reliable way > to do things (ActiveSupport uses it for the Time.zone stuff). The code > would look like (sketch): > > in application_controller.rb (or elsewhere): > > before_filter :set_customer_db > > def set_customer_db > Thread.current[:customer_db] = ... > end > > I can''t think of how exactly you''ll end up accessing it in the models, > but the magic_multi_connections gem should provide some guidance. > > --Matt Jones > > On Nov 2, 8:09 am, jmamma <jackli...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > Thanks Amar. Sharding isn''t exactly what I need here, but some > > interesting info nonetheless. > > > I have a main db ( users, applications, etc ) and a database for each > > customer ( products, orders, etc ) > > > When I want to get all the products, for example, I need to connect > > to > > a particular customers version of products. I can do it by using > > ActiveRecord::Base.establish_connection (:connection_name) in the > > controller > > but its not perfect... also there are some plugins that use some > > activeRecord > > stuff in them and the model doesn''t know which db its supposed to > > connect to > > so I have to modify all those gems and put the establish_connection in > > there too. > > > I put the customer in session on user login, and then I can easily get > > which customer > > db I need, but again that doesn''t work so well in the models since the > > session isn''t > > easily available in the models. > > > On Nov 2, 7:12 am, Amar Daxini <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > > wrote: > > > > jmamma wrote: > > > > Hey everyone! I have a problem that''s been making me a little nuts. > > > > I would like to use RoR for a upcoming project, but if I can''t get > > > > past this hiccup I''m > > > > afraid I''ll have to use PHP or Java. Ugh. > > > > check out data_fabric gemhttp://www.codefutures.com/database-sharding/andcheckthis article > > > -- > > > Posted viahttp://www.ruby-forum.com/.
jmamma wrote: [...]> Marnen - We need a db per customer for a few reasons. It will keep > the clients data separate ( some of them are weird like that about > their data, and require us to separate ), and also a particular > customer could have a customer feature they purchase that won''t make > sense > for all clients. That feature will cause for extra tables or columns > in that particular customers db that won''t be spread to everyone.None of these are good reasons to have a DB per customer, IMHO. These are all easily achieved with one DB. As far as your clients'' requirements, the structure of the DB is really not any of their business, and they are being unreasonable if they are trying to dictate your implementation.> > Also, this way we can easily backup a particular customer, or grab a > customer''s db a dump it on our local machine > really quick and test with their data, rather than pulling down a > giant db.You should be able to dump a subset without too much trouble.> > And finally, we can take down a particular customer rather easy and > not affect anyone else.Again, easy with one DB.> > I''m in some ways trying to convince myself that its a good thing to do > as well, since I don''t have much choice in the matter haha!Not a laughing matter. If you don''t have control over DB design, find another project. You''ve apparently been stuck with asinine requirements.> Thanks > for the input though!Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/.
Hi again Marnen. I think we''re a little off topic. The problem at hand is connecting to multiple databases, not poo poo''ing on the requirements haha! Thanks again for your input though! All thoughts are welcome. On Nov 2, 5:49 pm, Marnen Laibow-Koser <rails-mailing-l...@andreas- s.net> wrote:> jmamma wrote: > > [...] > > > Marnen - We need a db per customer for a few reasons. It will keep > > the clients data separate ( some of them are weird like that about > > their data, and require us to separate ), and also a particular > > customer could have a customer feature they purchase that won''t make > > sense > > for all clients. That feature will cause for extra tables or columns > > in that particular customers db that won''t be spread to everyone. > > None of these are good reasons to have a DB per customer, IMHO. These > are all easily achieved with one DB. As far as your clients'' > requirements, the structure of the DB is really not any of their > business, and they are being unreasonable if they are trying to dictate > your implementation. > > > > > Also, this way we can easily backup a particular customer, or grab a > > customer''s db a dump it on our local machine > > really quick and test with their data, rather than pulling down a > > giant db. > > You should be able to dump a subset without too much trouble. > > > > > And finally, we can take down a particular customer rather easy and > > not affect anyone else. > > Again, easy with one DB. > > > > > I''m in some ways trying to convince myself that its a good thing to do > > as well, since I don''t have much choice in the matter haha! > > Not a laughing matter. If you don''t have control over DB design, find > another project. You''ve apparently been stuck with asinine > requirements. > > > Thanks > > for the input though! > > Best, > -- > Marnen Laibow-Koserhttp://www.marnen.org > mar...-sbuyVjPbboAdnm+yROfE0A@public.gmane.org > -- > Posted viahttp://www.ruby-forum.com/.
2009/11/3 jmamma <jacklin10-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:> > Hi again Marnen. I think we''re a little off topic. > The problem at hand is connecting to multiple databases, not > poo poo''ing on the requirements haha! >Very often the solution to a problem is to change the approach so that the problem does not exist in the first place, rather than code around a tricky issue. To suggest such alternatives here is entirely valid. In a particular instance there may be a good reason for using the problematic approach of course. Colin
jmamma wrote:> Hi again Marnen. I think we''re a little off topic. > The problem at hand is connecting to multiple databases, not > poo poo''ing on the requirements haha!As Colin said, it is entirely appropriate to question the requirements here. You''re making your life difficult with these requirements, and you don''t seem to have a particularly good reason for them, so why keep them?> > Thanks again for your input though! All thoughts are welcome.If you really mean that, then please give my suggestions some serious consideration.> > On Nov 2, 5:49�pm, Marnen Laibow-Koser <rails-mailing-l...@andreas-Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/.