Creating and migrating a devise-driven User model in a main/replica context
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
When developing applications with high availability and scalability in mind, it becomes necessary to consider architectures beyond a single database. One common setup is having a main database (also known as primary or master) and one or more replica (slave) databases. This article will guide you through creating and migrating a User model in a Ruby on Rails application using the Devise gem in a main/replica database context.
Understanding Main/Replica Architecture
In a main/replica setup, the main database handles all write operations, while the replica handles read operations. This architecture helps in load distribution and increases read throughput, which is especially beneficial for read-heavy applications.
Setting Up Devise
Devise is a flexible authentication solution for Rails based on Warden. It provides a comprehensive suite of features and is easy to integrate and customize. To begin, add Devise to your Gemfile:
Run bundle install to install the gem. After that, you need to set up Devise in your Rails application:
This command creates the necessary configuration files and initializer under config/initializers/devise.rb.
Creating the User Model
Now, generate your User model using Devise:
This command constructs the model with default modules such as database authenticatable, registerable, recoverable, rememberable, trackable, and confirmable. Also, it automatically creates a migration file for the users table.
Configuring Database.yml
Your database.yml needs to reflect your main/replica setup. For instance:
Implementing Read/Write Split
To implement read/write split in Rails, you can use the active_record_slave gem or similar plugins which provide a mechanism to direct read queries to the replica. However, from Rails 6 onwards, you can also utilize the built-in Role and Sharding support to direct traffic to the appropriate database:
Handling Migrations
Migrations should always be run against the main database because the replica is typically read-only and receives updates via replication from the main database. Ensure that your migration scripts and Rails environment are configured to connect to the primary database when performing these migrations.
This command ensures that Rails connects to the primary database as specified in the database.yml.
Summary Table of Key Components
| Component | Description | Rails Command / Code |
| Devise Setup | Adding user authentication system to Rails. | rails generate devise:install |
| User Model | Creating the user model using Devise. | rails generate devise User |
| Database Config | Setting up YAML configuration for main/replica. | Edit config/database.yml |
| Read/Write Split | Configuring application to handle database roles. | connects_to database: {writing: :primary, reading: :replica} |
| Migrations | Running migrations on the main database. | RAILS_ENV=production bin/rails db:migrate |
Additional Considerations
- Error Handling: Implement robust error handling to address any connection issues with the replica.
- Monitoring and Failover: Set up monitoring for the databases and have a plan for failover in case the primary database goes down.
By following these steps, you can effectively set up and manage a Devise-driven User model in a main/replica database architecture, allowing your Rails application to scale efficiently while maintaining robust data integrity and availability.
Related reading
- Creation timestamp and last update timestamp with Hibernate and MySQL
- Dapper async and transaction
- Data allocation in the distributed databases
- Data can't be written in dolphindb distributed database
- Data modelling for dynamodb where entity has one to many and many to many relationships
- Data not distributed across cluster in Cassandra
- Data sharing/replication among some specific nodes in a distributed database or memory grid
- Data still remains in Kafka topic even after retention time/size

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.