Use Case: Maybe you need your multi tenant application database to partition horizontally (shard). Probably you want to store different customers data in different tables like customer_01, customer_02. But you don't want multiple models for these, but want to access data with single Model interface.

With Rails, you can achieve this very easily. Rails ActiveRecord::Base interface provides us a class method table_name. We'll use this to achieve our goal. We'll change this in runtime, dynamically.

Here is an example:

cTable4 ❯ rails c -e production
Running via Spring preloader in process 60375
Loading production environment (Rails 4.2.4)
irb(main):001:0> Book.first
  Book Load (0.1ms)  SELECT  "books".* FROM "books"  ORDER BY "books"."id" ASC LIMIT 1
=> #<Book id: 1, name: "ELoquent Ruby", author: "Russ", year: "2011", created_at: "2016-01-07 08:40:47", updated_at: "2016-01-07 08:40:47">
irb(main):002:0> Book.table_name = 'titles'
=> "titles"
irb(main):003:0> Book.first
  Book Load (0.2ms)  SELECT  "titles".* FROM "titles"  ORDER BY "titles"."id" ASC LIMIT 1
=> #<Book id: 1, title: "Practical OOD Ruby", author: "Sandi Metz">
irb(main):004:0>

For convenience, you might want to set some helper class methods.

class Customer < ActiveRecord::Base
  def self.change_to(id)
    self.table_name = "customer_#{id}"
  end
end

Now you can simple call that method and change the table:

Customer.change_to(06)

Yes, it's that simple. Happy development :)

If you've any other tips in mind, don't forget to share with us in the comments.




What's on your mind?


538 Comments