Rails 6.1 creates abstract classes in multiple database mode

Akhil Gautam

Akhil Gautam

August 4, 2020

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.


class Person < ApplicationRecord
connects_to database: { writing: :crm }
end

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.

class Person < ApplicationRecord
connects_to database: { writing: :crm }
end

class Order < ApplicationRecord
connects_to database: { writing: :crm }
end

class Sale < ApplicationRecord
connects_to database: { writing: :crm }
end

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.

class CrmRecord < ApplicationRecord
self.abstract_class = true

connects_to database: { writing: :crm }
end

class Person < CrmRecord
end

class Order < CrmRecord
end

class Sale < CrmRecord
end

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.

$ 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.


# app/models/users_record.rb

class CrmRecord < ApplicationRecord
self.abstract_class = true

connects_to database: { writing: :crm }
end

# app/models/admin.rb

class Person < CrmRecord
end

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.

$ 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.

If this blog was helpful, check out our full blog archive.

Stay up to date with our blogs.

Subscribe to receive email notifications for new blog posts.