{"id":13835617,"url":"https://github.com/ankane/multiverse","last_synced_at":"2025-07-10T10:30:45.044Z","repository":{"id":55157851,"uuid":"109220685","full_name":"ankane/multiverse","owner":"ankane","description":"Multiple databases for Rails :tada:","archived":true,"fork":false,"pushed_at":"2022-12-26T19:39:51.000Z","size":70,"stargazers_count":462,"open_issues_count":0,"forks_count":19,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-10-31T14:49:24.897Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ankane.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-02T05:16:21.000Z","updated_at":"2024-06-25T04:36:17.000Z","dependencies_parsed_at":"2023-01-31T00:50:12.532Z","dependency_job_id":null,"html_url":"https://github.com/ankane/multiverse","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fmultiverse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fmultiverse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fmultiverse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankane%2Fmultiverse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ankane","download_url":"https://codeload.github.com/ankane/multiverse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225632929,"owners_count":17499889,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T14:01:06.452Z","updated_at":"2024-11-20T21:31:11.232Z","avatar_url":"https://github.com/ankane.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# Multiverse\n\n:fire: Multiple databases for Rails\n\n**ActiveRecord supports multiple databases, but Rails \u003c 6 doesn’t provide a way to manage them.** Multiverse changes this.\n\nPlus, it’s easy to [upgrade to Rails 6](#upgrading-to-rails-6) when you get there.\n\nWorks with Rails 4.2+\n\n[![Build Status](https://github.com/ankane/multiverse/workflows/build/badge.svg?branch=master)](https://github.com/ankane/multiverse/actions)\n\n## Installation\n\nAdd this line to your application’s Gemfile:\n\n```ruby\ngem 'multiverse'\n```\n\n## Getting Started\n\nIn this example, we’ll have a separate database for our e-commerce catalog that we’ll call `catalog`.\n\nThe first step is to generate the necessary files.\n\n```sh\nrails generate multiverse:db catalog\n```\n\nThis creates a `CatalogRecord` class for models to inherit from and adds configuration to `config/database.yml`. It also creates a `db/catalog` directory for migrations and `schema.rb` to live.\n\n`rails` and `rake` commands run for the original database by default. To run commands for the new database, use the `DB` environment variable. For instance:\n\nCreate the database\n\n```sh\nDB=catalog rails db:create\n```\n\nCreate a migration\n\n```sh\nDB=catalog rails generate migration add_name_to_products\n```\n\nRun migrations\n\n```sh\nDB=catalog rails db:migrate\n```\n\nRollback\n\n```sh\nDB=catalog rails db:rollback\n```\n\n## Models\n\nAlso works for models\n\n```sh\nDB=catalog rails generate model Product\n```\n\nThis generates\n\n```rb\nclass Product \u003c CatalogRecord\nend\n```\n\n## Web Servers\n\n*Only necessary in Rails \u003c 5.2*\n\nFor web servers that fork, be sure to reconnect after forking (just like you do with `ActiveRecord::Base`)\n\n### Puma\n\nIn `config/puma.rb`, add inside the `on_worker_boot` block\n\n```ruby\nCatalogRecord.establish_connection :\"catalog_#{Rails.env}\"\n```\n\n### Unicorn\n\nIn `config/unicorn.rb`, add inside the `before_fork` block\n\n```ruby\nCatalogRecord.connection.disconnect!\n```\n\nAnd inside the `after_fork` block\n\n```ruby\nCatalogRecord.establish_connection :\"catalog_#{Rails.env}\"\n```\n\n## Testing\n\n### Fixtures\n\n[Rails fixtures](https://guides.rubyonrails.org/testing.html#the-low-down-on-fixtures) work automatically.\n\n**Note:** Referential integrity is not disabled on additional databases when fixtures are loaded, so you may run into issues if you use foreign keys. Also, you may run into errors with fixtures if the additional databases aren’t the same type as the primary.\n\n### RSpec\n\nAfter running migrations for additional databases, run:\n\n```sh\nDB=catalog rails db:test:prepare\n```\n\n### Database Cleaner\n\nDatabase Cleaner supports multiple connections out of the box.\n\n```ruby\ncleaner = DatabaseCleaner[:active_record, {model: CatalogRecord}]\ncleaner.strategy = :transaction\ncleaner.cleaning do\n  # code\nend\n```\n\n[Read more here](https://github.com/DatabaseCleaner/database_cleaner#how-to-use-with-multiple-orms)\n\n## Limitations\n\nThere are a few features that aren’t supported on additional databases.\n\n- Pending migration check\n- `schema_cache.yml`\n\nAlso note that `ActiveRecord::Migration.maintain_test_schema!` doesn’t affect additional databases.\n\n## Upgrading to Rails 6\n\nRails 6 provides a way to manage multiple databases :tada:\n\nTo upgrade from Multiverse, nest your database configuration in `config/database.yml`:\n\n```yml\n# this should be similar to default, but with migrations_paths\ncatalog_default: \u0026catalog_default\n  adapter: ...\n  pool: \u003c%= ENV.fetch(\"RAILS_MAX_THREADS\") { 5 } %\u003e\n  migrations_paths: db/catalog_migrate\n\ndevelopment:\n  primary:\n    \u003c\u003c: *default\n    database: ...\n  catalog:\n    \u003c\u003c: *catalog_default\n    database: ...\n\ntest:\n  primary:\n    \u003c\u003c: *default\n    database: ...\n  catalog:\n    \u003c\u003c: *catalog_default\n    database: ...\n\nproduction:\n  primary:\n    \u003c\u003c: *default\n    database: ...\n  catalog:\n    \u003c\u003c: *catalog_default\n    database: ...\n```\n\nThen change `establish_connection` in `app/models/catalog_record.rb` to:\n\n```rb\nclass CatalogRecord \u003c ActiveRecord::Base\n  establish_connection :catalog\nend\n```\n\nAnd move:\n\n- `db/catalog/migrate` to `db/catalog_migrate`\n- `db/catalog/schema.rb` to `db/catalog_schema.rb` (or `db/catalog/structure.sql` to `db/catalog_structure.sql`).\n\nThen remove `multiverse` from your Gemfile. :tada:\n\nNow you can use the updated commands:\n\n```sh\nrails db:migrate          # run all\nrails db:migrate:catalog  # runs catalog only\n```\n\nGenerate migrations with:\n\n```sh\nrails generate migration add_name_to_products --database=catalog\n```\n\nAnd models with:\n\n```sh\nrails generate model Product --database=catalog --parent=CatalogRecord\n```\n\nHappy scaling!\n\n## History\n\nView the [changelog](https://github.com/ankane/multiverse/blob/master/CHANGELOG.md)\n\n## Contributing\n\nEveryone is encouraged to help improve this project. Here are a few ways you can help:\n\n- [Report bugs](https://github.com/ankane/multiverse/issues)\n- Fix bugs and [submit pull requests](https://github.com/ankane/multiverse/pulls)\n- Write, clarify, or fix documentation\n- Suggest or add new features\n\nTo get started with development and testing:\n\n```sh\ngit clone https://github.com/ankane/multiverse.git\ncd multiverse\nbundle install\nbundle exec rake test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fankane%2Fmultiverse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fankane%2Fmultiverse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fankane%2Fmultiverse/lists"}