DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Providing Enum Consistency Between Application and Data
  • How to Build a Full-Stack App With Next.js, Prisma, Postgres, and Fastify
  • Enterprise RIA With Spring 3, Flex 4 and GraniteDS
  • How Java Apps Litter Beyond the Heap

Trending

  • Rethinking Recruitment: A Journey Through Hiring Practices
  • Docker Model Runner: Streamlining AI Deployment for Developers
  • Create Your Own AI-Powered Virtual Tutor: An Easy Tutorial
  • AI Meets Vector Databases: Redefining Data Retrieval in the Age of Intelligence
  1. DZone
  2. Data Engineering
  3. Data
  4. Rails 6: Multiple DB Support

Rails 6: Multiple DB Support

Learn about Rails 6 and it's multiple databases support and see why you want this support.

By 
Ajay Babar user avatar
Ajay Babar
·
Mar. 03, 20 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
8.9K Views

Join the DZone community and get the full member experience.

Join For Free

With the launch of Rails 6, one of the new features that was announced was for multiple DB support. This breather came to me when, in one of our applications, I was struggling to efficiently manage separate DBs. There are a number of reasons why one would want such support, such as:

  • Using the SQL database for storing user data and NoSQL for location data
  • Having multiple SQL databases to manage separate apps but an app might need direct access to the other DB
  • Managing multiple NoSQL and Redis databases to store different kinds of data, etc.

When faced with using multiple databases, usually one serves as a master and the other servers as a slave. Because I was managing this before the release of Rails 6, I was using a not-so-optimal (read patched/hacky) way to get this done. I created a separate YAML file for the second database to store the connection information. Here is a sample file: 

Java
 




x


 
1
second_database.yaml
2

          
3
  adapter: db_adapter
4
  encoding: db_encoding
5
  pool: db_pool
6
  username: db_username
7
  password: db_password
8
  database: db_name
9
  host: db_host



To access multiple databases, every time I would: 

  • Establish the connection by reading the connection information from the YAML file

Java
 




xxxxxxxxxx
1


 
1
config = YAML.load_file(second_database.yaml')
2
connection = ActiveRecord::Base.establish_connection(
3
  adapter:  config['adapter'],
4
  host:     config['host'],
5
  database: config['database'],
6
  username: config['username'],
7
  password: config['password']
8
)
9

          


 

  • Query the data
Java
 




xxxxxxxxxx
1


 
1
employees = connection.execute("SELECT * from employees")


 

  • close the connection

Java
 




xxxxxxxxxx
1


 
1
connection.close



You might also like: Rails Bundle Install and Gemfile

Such a headache!

But with the release of the new Rails 6, you probably won’t have to go through the pain (and squirm at your own code) to manage multiple databases.

As soon as Rails 6 was launched, I upgraded my application to leverage the benefits of multiple DB support. Let’s go step by step to understand the upgrade and set up for multiple DBs.

  1. First, check and update Ruby to version to 2.5, as Rails 6 requires Ruby 2.5 or newer.
  2. Upgrade your Ruby version to 2.5 or newer:

    1. During the Ruby update, it might be possible to get syntax errors or deprecation warnings just because of a version upgrade

    2. Please update Ruby versions incrementally — do not directly jump to the latest version; this will cause you lots of issues

    3. Update to the next incremented version; resolve the errors and warnings; run and resolve the test cases and repeat the process

  3. Upgrade Rails to the latest version in 5.2 series:
    1.  As this article only covers upgrade guidelines from Rails 5.2 to Rails 6; please make sure you’re on the latest version in the 5.x series.
  4. Update Gemfile for Rails 6 version:

    1. Now it’s time to update the Rails version in your Gemfile; change the Rails Gem version in your Gemfile.

    2. Run the bundle update Rails command in the terminal to update Rails and other dependent Gems.

  5. Run the Rails app:update in terminal:

    1. By running this command; you will find some new config settings are added to your application. I suggest you use the diff tool option (d) for each file change.

  6. Uncomment defaults values in new_framework_defaults_6_0.rb:

  7. Run migration:
    1. Now run the bundle install to install the remaining Gems and run the migration and resolve the issue if any

  8. Run and fix TestCases:

    1. After this massive upgrade, let’s test your application. Run your TestCases; solve if any failed, and solve deprecation warning.
  9. Start the localhost and perform manual testing:

    1. I would suggest you do one round of manual testing for your app. Hit the rails s and start testing your app manually.

Bingo, now you run on Rails 6!

Now let’s move further for multiple DB setup with Rails 6.

With Rails 6 multiple DB support, you can have more than one database with a replica (read-only copy) of each database.

Now, consider your Rails application with a single primary database and now after upgrading to Rails 6, you need to add a new database for some of the new tables. The current version of your database.yml looks like:

Java
 




xxxxxxxxxx
1


 
1
production:
2
  database: my_primary_database
3
  user: root
4
  adapter: mysql



With Rails 6; you can add a replica for your primary database and also can add a new database by updating your database.yml like this:

Java
 




xxxxxxxxxx
1
20


 
1
production:
2
  primary:
3
    database: my_primary_database
4
    user: root
5
    adapter: mysql
6
  primary_replica:
7
    database: my_primary_database
8
    user: root_readonly
9
    adapter: mysql
10
    replica: true
11
  blogs:
12
    database: my_blogs_database
13
    user: blogs_root
14
    adapter: mysql
15
    migrations_paths: db/blogs_migrate
16
  blogs_replica:
17
    database: my_blogs_database
18
    user: blogs_readonly
19
    adapter: mysql
20
    replica: true



Consider a few points that you need to heed when using replica for your database:

  • For primary and replica databases, the database name should be the same because both the databases contain the same data. While using the replica database, you need to add  replica: true  to the database settings.

  • The username for both the replica and the primary databases should be different; the primary user would have both read and write permissions while the replica user would have only read permission.

  • While adding a new database, you need to take care of the migrations path as well. For it, you need to add a migrations_path  setting in the database.yml file as shown above. We haven’t set migrations path for the replica database, but we have replica: true for it.

After this step; you will have a new database added. Now let’s set up a model for it. To use a new database, you need to add one abstract model class to your app as shown below:

Java
 




xxxxxxxxxx
1


 
1
class Post < ApplicationRecord
2
  self.abstract_class = true
3
 
4
  connects_to database: { writing: :blogs, reading: :blogs_replica }
5
end



Now that you can access the new database, let’s briefly discuss multiple database features:

1. Automatic connection switching between primary and replica database: 

To use a read-only database to the application, you need to configure middleware for automatic connection switching.

Automatic connection switching allows your application to switch between primary and replica databases based on HTTP request methods.

To configure middleware for automatic connection switching, uncomment or add the following line to application config.

Java
 




xxxxxxxxxx
1


 
1
config.active_record.database_selector = 2.seconds



Rails only sends a GET or HEAD request to the primary only if the read request is within what we configured above. By default, it will be set to 2 seconds. You can change it based on your database infrastructure.

2. Manual connection switching between primary and replica database: 

To connect to the replica or primary database manually; Rails provides the ActiveRecord::Base.connected_to method.

There are some cases where your application needs to connect to primary or replica without bothering with the request type. In such cases, you can utilize the connected_to  method provided by ActiveRecord.

Java
 




xxxxxxxxxx
1


 
1
ActiveRecord::Base.connected_to(database: blogs) do
2
  CollectPostsInformationWorker.perform(Post.all.pluck(:id, :title))
3
end



By using the above code, you can force your application to connect to blogs database irrespective of the request type.

Java
 




xxxxxxxxxx
1


 
1
ActiveRecord::Base.connected_to(database: { reading: :blogs }) do
2
  CollectPostsInformationWorker.perform(Post.all.pluck(:id, :title))
3
end



This will use the connection to read the replica of the blog's database and use it.

Now, let’s see what features Rails 6 does not provide with a multi-DB feature.

Features such as sharding, load balancing of replicas, and joining across the multiple databases are not supported in Rails 6.

Some of these features may hopefully be added in the future.

Further Reading

Rails Logger and Rails Logging Best Practices

Database application Java (programming language) Connection (dance) app Data (computing) Requests GEM (desktop environment) Load balancing (computing)

Opinions expressed by DZone contributors are their own.

Related

  • Providing Enum Consistency Between Application and Data
  • How to Build a Full-Stack App With Next.js, Prisma, Postgres, and Fastify
  • Enterprise RIA With Spring 3, Flex 4 and GraniteDS
  • How Java Apps Litter Beyond the Heap

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!