This blog is part of our Rails 6.1 series.
Rails started supporting multiple databases from Rails 6.0. To use a specific database, we can specify the database connection in the model using connects_to. In the following case we want Person model to connect to crm database.
1 2class Person < ApplicationRecord 3connects_to database: { writing: :crm } 4end 5
As the application grows, more and more models start sharing the same database. Now a lot of models may contain connects_to call to the same database.
1class Person < ApplicationRecord 2connects_to database: { writing: :crm } 3end 4 5class Order < ApplicationRecord 6connects_to database: { writing: :crm } 7end 8 9class Sale < ApplicationRecord 10connects_to database: { writing: :crm } 11end
In order to avoid the duplication, we can create an abstract class connecting to a database and manually inherit all other models from that class. This could look like this.
1class CrmRecord < ApplicationRecord 2self.abstract_class = true 3 4connects_to database: { writing: :crm } 5end 6 7class Person < CrmRecord 8end 9 10class Order < CrmRecord 11end 12 13class Sale < CrmRecord 14end
Rails 6.1
Before Rails 6.1 we had no choice but to create that abstract class manually. Rails 6.1 allows us to generate an abstract class when we are generating a model using scaffold.
1$ rails g scaffold Person name:string --database=crm
It creates an abstract class with the database's name appended with Record. The generated model automatically inherits from the new abstract class.
1 2# app/models/users_record.rb 3 4class CrmRecord < ApplicationRecord 5self.abstract_class = true 6 7connects_to database: { writing: :crm } 8end 9 10# app/models/admin.rb 11 12class Person < CrmRecord 13end
If the abstract class already exists, it is not created again. We can also use an existing class as the abstract class by passing parent option to the scaffold command.
1$ rails g scaffold Customer name:string --database=crm --parent=PrimaryRecord
This skips generating CrmRecord class as we have specified Rails to use PrimaryRecord abstract class as its parent.
Check out the pull request for more details on this.