Allows you to use multiple databases with ActiveRecord 6, with
optional support for Rails’s migration generator (rails generate migration ..
).
Our documentation uses YARD, you may want to see the generated documentation instead of Github README.
The project consists from two parts, the core library multi_ar
and supplementary library multi_ar_migrations
,
where former implements everything needed for usage of multiple databases in any application and latter providers
migration infrastructure for creating migrations for development needs.
- Streamlined way of using multiple databases with ActiveRecord
- Standard production/development/test (or whatever you want) labels
- CLI interface that allows fast creation of scripts using ActiveRecord models
- Works across different ActiveRecord versions; instead of using private, version dependent API, internal parts have been implemented in this project.
$ gem install multi_ar multi_ar_migrations
or with Bundler
# In Gemfile
gem "multi_ar"
group :development do
gem "multi_ar_migrations"
end
and then install the bundle:
$ bundle install
# Look what you can do
$ multi_ar --help
# Create your new project
$ mkdir shiny_new_project
$ cd shiny_new_project
# Initialize the project
$ multi_ar --init
# Configure databases
$ vi config/database.yaml # change foo in foo_development to one of databases in multi_ar -l
# List rake tasks that the gem supports
$ multi_ar -T
# Read documentation of db:new_migration
$ multi_ar -t db:new_migration -d my_database
# Create new migration for database my_database
$ multi_ar -t db:new_migration[NewMigraine] -d my_database
# Run migrations for all databases
$ multi_ar -t db:migrate
Migrations can also be run directly from a gem. Any gem that has a special configuration file config/multi_ar_gem.yaml
,
which contains following data:
migration_dir: db/migrate
After the gem has been installed to target system, the migrations can be run with multi_ar
executable:
multi_ar --gem YOUR_GEM --task db:migrate --databases "your_databases"
There is few different ways of using the API, by subclassing {MultiAR::MultiAR}, by using {MultiAR::MultiAR} directly and by implementing your own executable using {MultiAR::Interface}.
Models works like standard ActiveRecord models, with exception that they should be inherited from your custom model.
With multiple databases, you need to define connections in your models. For convenience, it’s usually good idea to do one model per database, where your connection details to that database resides.
For example, if you have table named my_new_models
in database my_database
, you may want to save your model
to path like lib/my_database/my_new_model.rb
:
require_relative "../model"
module MyDatabase
class MyNewModel < MyDatabase::Model
end
end
And then at lib/my_database/model.rb
you’d have your custom model.rb
:
require "multi_ar/model"
module MyDatabase
class Model < MultiAR::Model
# Needed so ActiveRecord can determine correct names
self.abstract_class = true
# Database identifier, for example for development environment, you’d have my_database_development:
# database settings block, as opposed to ActiveRecord’s standard development: block.
# Environment will be applied to the name automatically by MultiAR, as specified to MultiAR#new.
establish_connection "my_database"
end
end
ActiveRecord models that uses MultiAR requires {MultiAR::MultiAR MultiAR} object initialized before the models will work. This object takes care of settings handling and saves information about all databases that has been used.
@multi_ar = MultiAR::MultiAR.new databases: [ "my_database" ], environment: "development"
Afterwards, you can use your models as you’d use them with pure ActiveRecord:
require "my_new_model"
puts MyNewModel.count
For further customization, {MultiAR::MultiAR MultiAR} class can also be subclassed, which allows you to do ready deployment packages, and for example package them as a gem, which knows how to handle all your specific settings without any extra information from the user.
require "multi_ar"
module MyApplication
# Wrapper over MultiAR’s base class
class MyMultiAR < MultiAR::MultiAR
add_migration_dir "my_db_migrate/dir"
end
end
MultiAR can be used with {http://www.sinatrarb.com/ Sinatra}, for example, without any real extra trouble. If you wish to launch
{http://www.sinatrarb.com/ Sinatra} as executable (by ruby yourservice.rb
or ./yourservice
for example),
it may make sense to use {MultiAR::Interface MultiAR’s CLI interface support} instead:
# This example executable resides in bin/yourservice
require "multi_ar/interface"
require_relative "../lib/yourservice/version"
interface = MultiAR::Interface.new
interface.version = "yourservice-#{Yourservice::VERSION}"
interface.description = "My totally useful utility no-one can live without."
# interface.migration_framework = true # Enables Rake tasks for migration generation; not needed unless you plan to generate migrations with this executable
interface.options["databases"] = true
opts = interface.cli do |parser|
# You can add your custom optimist options here
parser.opt :port, "Port where to bind Sinatra", default: "9999", type: :string
end
# MultiAR will be initialized by `MultiAR::Interface`, so now you can just run your program as you want
raise "Invalid port" if opts["port"] != 10001
require 'sinatra'
get '/hi' do
"Hello World!"
end
Then you can just run your application:
$ bundle exec ruby bin/yourservice.rb
- Ruby 2.1 or greater
$ gem install bundler
$ bundle install
$ cucumber
# write new feature
$ cucumber
# rinse and repeat :-)
You can do pull requests at Github using the standard pattern :-)
- Fork it
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create new Pull Request
(The MIT License)
Copyright (c) 2019 Samu Voutilainen
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This gem is inspired by code of active_record_migrations.