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

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

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

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

  • Ethical AI in Agile
  • How To Introduce a New API Quickly Using Quarkus and ChatGPT
  • MCP Servers: The Technical Debt That Is Coming
  • Blue Skies Ahead: An AI Case Study on LLM Use for a Graph Theory Related Application
  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!