Dynamically create databases?

591 views
Skip to first unread message

Johan Vauhkonen

unread,
Apr 4, 2013, 2:29:19 AM4/4/13
to rubyonra...@googlegroups.com
Is it possible to dynamically create new databases and tables within them with Rails?

Or is that a task best done manually?

I'm creating an application which should allow users to store their own statistics information (which can and probably with time will be a lot).
My initial thought was to give each user their own database to keep their data separate from each other due to the possible large quantity of data each user will have.

Good idea? Bad idea? Other ways to do it?

Julian Leviston

unread,
Apr 4, 2013, 2:38:19 AM4/4/13
to rubyonra...@googlegroups.com
Yes, and yes.

That sounds fine.

Just be careful not to optimise prematurely (ie... make design decisions with a VIEW to the future, but don't let that both you too much in the present). Chances are when it comes to architecture and optimisation, Ya Aint Gonna Need It, and when you do, it'll most likely be different than you think it will be now.

Focus more on the classes in your system than how to efficiently store them at the inception/design stage.

Julian

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/ZRLrcnKJ-fsJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Johan Vauhkonen

unread,
Apr 4, 2013, 3:05:11 AM4/4/13
to rubyonra...@googlegroups.com
Thanks for replying, Julian.

Can you point me to any resources that describe how to do it?

I agree that I should not optimize prematurely but what I'm considering is which is easier,
to go with dynamically creating databases from the start or to extract data from the single database to new databases later on?

It's at least something to keep in the back of my mind.

Colin Law

unread,
Apr 4, 2013, 3:10:14 AM4/4/13
to rubyonra...@googlegroups.com
What do you mean by a large quantity of data? Modern databases can
manage vast amounts of data efficiently. It is very rare for the
bottlenecks in a system to be where you expect them to be when you
start out and it is very likely that you will find that the extra work
was a waste of time. Start with a single database and make sure you
have good automated test coverage. Then in the unlikely event that
you find that you do have split the database then you can refactor the
code and the tests will help to ensure that you have not messed
anything up.

Colin

Julian Leviston

unread,
Apr 4, 2013, 3:18:03 AM4/4/13
to rubyonra...@googlegroups.com
Hi,

You shouldn't attempt to do this if you don't already understand enough Ruby / Rails to do it yourself.

So, I suggest sticking with what you *can* do first.

This might sound like a cop out, but there's very good reason. It's very advanced Rails and you really shouldn't attempt something like this until you understand the basics really well IMHO.

Julian

Johan Vauhkonen

unread,
Apr 4, 2013, 3:43:30 AM4/4/13
to rubyonra...@googlegroups.com
Thanks for posting, I appreciate the feedback.

I'll start with keeping everything within a single database and take it from there.

You are right Julian in that I am new with RoR and what I've asked for is advanced.

I'm still curious though how creating databases dynamically would be done so if it's explained anywhere I'd love to read it!


2013/4/4 Julian Leviston <jul...@coretech.net.au>

--
You received this message because you are subscribed to a topic in the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rubyonrails-talk/S73DxPeqvy4/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to rubyonrails-ta...@googlegroups.com.

To post to this group, send email to rubyonra...@googlegroups.com.

Jeffrey Jones

unread,
Apr 4, 2013, 4:29:28 AM4/4/13
to rubyonra...@googlegroups.com
Assuming you are using postgresql you might be interested in this railscast (paid)

http://railscasts.com/episodes/389-multitenancy-with-postgresql

Which takes advantage of being able to have multiple schemas in PostgreSQL.

Be aware though that it will make your initial coding more complicated and will
have knock-on effects for things like testing etc.

Basically, it will do what you want but it will not be free in terms of development effort.

I echo other statements that this may be premature optimisation, look at the railscast, give
it a try yourself and see if the trade-off is good enough for you.

(If you do not want to pay for railscasts then have a look at this gem: https://github.com/influitive/apartment)
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.

Julian Leviston

unread,
Apr 4, 2013, 4:34:21 AM4/4/13
to rubyonra...@googlegroups.com
Okay...

So to do this, you need to understand meta-programming to a degree because that's what you're doing.

In normal Rails, you'd create a model as part of the development process, but what you're doing is creating some code that creates models itself (ie one level of abstraction higher than normal).

The equivalent straight ruby comparison is: (compare 1, with 2, below):

1. Creating a class (this is normal programming)

class Cat
  def hi
    puts 'meow'
  end
end

You can then create new Cat objects like this:
furrycat = Cat.new

and make it meow like this:
furrycat.hi

2. Creating a piece of code that creates a class (this is meta-programming)

a_class = Class.new
hi_method_block = Proc.new{ puts 'meow' }
a_class.send(:define_method, :hi, &hi_method_block)

You can then create new "Cat" objects like this:
furrycat = a_class.new

and make it meow like this:
furrycat.hi

---

So...  assuming you followed that, then you'll understand that you could do the same thing with ActiveRecord::Base classes, which is what forms the bases for Active Record model classes. This is how you'd dynamically LOAD one of your programmatically generated models. Creating the table is just a matter of executing some arbitrary SQL which can be built using ActiveRecord::Base.connection.execute. (Eg to run a count of a fictitious users table, you'd do this: ActiveRecord::Base.connection.execute("SELECT COUNT(*) FROM users;")

However, like I said, there's no point trying to do this until you can walk, because this really is running. Most Rails devs hardly ever get into this stuff. I've been a Rails developer since 2005, and I've only done this sort of dynamic table and database thing once or twice in practice.

Julian

You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.

Simon Macneall

unread,
Apr 4, 2013, 5:18:37 AM4/4/13
to rubyonra...@googlegroups.com
We have toyed with creating separate databases for each customer as our
combined one is starting to get quite large. In our case, the models will
always be the same no matter which database you are connecting to, so
there isn't any meta-programming involved. It's just a case of switching
databases to the correct one for that customer once they log into the
system.

One thing to consider is that shared data needs to go somewhere (sessions,
username/passwords etc) as well.

Cheers
Simon

Johan Vauhkonen

unread,
Apr 4, 2013, 5:24:18 AM4/4/13
to rubyonra...@googlegroups.com
That kind of scenario was what I had initially in mind. Everyone has
the same models, just not the same database.

2013/4/4, Simon Macneall <macn...@gmail.com>:

Pedro Marques

unread,
Feb 17, 2016, 7:03:59 AM2/17/16
to Ruby on Rails: Talk, johan.v...@gmail.com
Hello!

I know three years have passed, but I am looking to do exactly what you proposed on your first post, so I am interested in knowing if you have managed to so and if you did, how did you do it?

Thanks in advance.

jackso...@gmail.com

unread,
Oct 3, 2016, 3:07:20 AM10/3/16
to Ruby on Rails: Talk, johan.v...@gmail.com
Faced a similar problem today and thought I'd post my solution. To figure this out I looked through the rails database.rake codebase: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railties/databases.rake#L16


ActiveRecord::Base.configurations["newdb"] = {
 
"adapter" => 'mysql2',
 
"encoding" => 'utf8',
 
"reconnect" => false,
 
"database" => 'newdb',
 
"pool" => 5,
 
"username" => '[username]',
 
"password" => '[password]',
 
"host" => '127.0.0.1',
 
"port" => 3306,
}
ActiveRecord::Tasks::DatabaseTasks.env = 'newdb'
ActiveRecord::Tasks::DatabaseTasks.create # Creates the database, empty.
ActiveRecord::Tasks::DatabaseTasks.migrate # Runs migrations against the new empty database.
Reply all
Reply to author
Forward
0 new messages