Skip to content

riboseinc/container_record

Repository files navigation

ContainerRecord: Two-tier ActiveRecord functionality

Rails' ActiveRecord ("AR") is implemented on the level of tables, such that each AR model corresponds to a table.

ContainerRecord ("CR") however implements an additional tier on top of AR, that implements AR-styled functionality on the database level.

Usage

To start using ContainerRecord you need to create an external_databases table in your main database. The name is fully optional, as well as the structure.

The idea is that you store a database connection settings there, like if you would store them in your standard Rails config/database.yml.

Column names should match the keys available in config/database.yml.

Example

Assuming you have a Company model in your Rails application. It is just a regular model, which has its own table, and so on:

# app/models/company.rb
class Company < ActiveRecord::Base
  has_many :employees
end

# app/models/employee.rb
class Employee < ActiveRecord::Base
  belongs_to :company
end

Let’s say you have 5 companies, and now you want to store their employees each in its own database. Easy - with ContainerRecord!

Just add gem 'container_record', '~> 1.0' to your Gemfile, and change your Company model the following way:

# app/models/company.rb
class Company < ActiveRecord::Base
  include ContainerRecord::ExternalDatabase

  has_external :employees

  database_name ->(company) { "#{company.name}_#{company.id}_database" }
end

# app/models/employee.rb
class Employee < ActiveRecord::Base
  # Note, we disabled belongs_to relation, as companies now live in a different database
  # belongs_to :company
end

# config/initializers/container_record.rb
ContainerRecord.configure do |config|
  config.external_database_classes = [Company]
end

That’s pretty much it!

Don’t forget to create a new database for every company (i.e. twitter_1_database, jacksonandsons_2_database etc), and migrate there your smaller "employees" table.

Now you’re able to access them just like that:

company = Company.find(1)
company.employees.where(salary: 75_000)
company.create_external_record(Employee, first_name: 'Robert', salary: 80_000)

Plans & TODOs

  • ❏ To add simple migrations for external databases (aka maintain actual DB version)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages