Rails does not require role when to be passed to connected_to

Rails has powerful sharding features available right within ActiveRecord. It is possible to define either vertical or horizontal shards and use connected_to to switch between them. When execution happens inside the method, all database connections follow the configuration specified in the connected_to block.

To configure our shards, we use the config/database.yml file. Here’s how ours looks.

development:
  primary:
    <<: *default
    database: primary_database
  primary_shard_two:
    <<: *default
    database: primary_shard_two
  primary_shard_two_replica:
    <<: *default
    database: primary_shard_two
    replica: true

Then we initiate the connection in ApplicationRecord.

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to shards: {
    default: { writing: :primary, reading: :primary_replica },
    shard_two: { writing: :primary_shard_two, reading: :primary_shard_two_replica }
  }
end

Note that primary and primary_shard_two are not replicas of each other. Rather, they are independent databases which share the same schema. The primary_replica and primary_shard_two_replica are replicas.

Before

Originally two parameters were required for a connected_to block – the name of the shard and the role. This was done to make it less syntactically confusing to use.

Let’s look at an example.

ActiveRecord::Base.connected_to(role: :reading, shard: :default) do
  puts ActiveRecord::Base.connection_db_config.name
  Blog.count
end

primary_replica
  Blog Count (3.1ms)  SELECT COUNT(*) FROM "blogs"
=> 3

However, if we don’t specify the role parameter, Rails throws an ArgumentError.

ActiveRecord::Base.connected_to(shard: :default) do
  puts ActiveRecord::Base.connection_db_config.name
  Blog.count
end

Traceback (most recent call last):
  1: from (irb):1
ArgumentError (`connected_to` cannot accept a `shard` argument without a `role`.)

After

Changes to this PR remove the need for role to be passed to every connected_to block.

This was done to prevent the need for a role parameter from being passed when execution was only concerned with the shared. It also paves the way for more complex multi-tenancy work to be done later on while also simplifying calls for applications that don’t use roles, rather only have writer shards.

Need help on your Ruby on Rails or React project?

Join Our Newsletter