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.

Join Our Newsletter