Class: ActiveRecord::Middleware::ShardSelector
Relationships & Source Files | |
Inherits: | Object |
Defined in: | activerecord/lib/active_record/middleware/shard_selector.rb |
Overview
Shard Selector Middleware
The ShardSelector ::ActiveRecord::Middleware
provides a framework for automatically swapping shards. Rails provides a basic framework to determine which shard to switch to and allows for applications to write custom strategies for swapping if needed.
Setup
Applications must provide a resolver that will provide application-specific logic for selecting the appropriate shard. Setting config.active_record.shard_resolver
will cause ::Rails
to add ShardSelector
to the default middleware stack.
The resolver, along with any configuration options, can be set in the application configuration using an initializer like so:
Rails.application.configure do
config.active_record.shard_selector = { lock: false, class_name: "AnimalsRecord" }
config.active_record.shard_resolver = ->(request) {
subdomain = request.subdomain
tenant = Tenant.find_by_subdomain!(subdomain)
tenant.shard
}
end
Configuration
The behavior of ShardSelector
can be altered through some configuration options.
lock:
-
lock
is true by default and will prohibit the request from switching shards once inside the block. Iflock
is false, then shard switching will be allowed. For tenant based sharding,lock
should always be true to prevent application code from mistakenly switching between tenants. class_name:
-
class_name
is the name of the abstract connection class to switch. By default, the ShardSelector will use ActiveRecord::Base, but if the application has multiple databases, then this option should be set to the name of the sharded database’s abstract connection class.
Class Method Summary
Instance Attribute Summary
Instance Method Summary
- #call(env)
- #selected_shard(request) private
- #set_shard(shard, &block) private
Constructor Details
.new(app, resolver, options = {}) ⇒ ShardSelector
Instance Attribute Details
#options (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/shard_selector.rb', line 53
attr_reader :resolver, :
#resolver (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/shard_selector.rb', line 53
attr_reader :resolver, :
Instance Method Details
#call(env)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/shard_selector.rb', line 55
def call(env) request = ActionDispatch::Request.new(env) shard = selected_shard(request) set_shard(shard) do @app.call(env) end end
#selected_shard(request) (private)
[ GitHub ]#set_shard(shard, &block) (private)
[ GitHub ]# File 'activerecord/lib/active_record/middleware/shard_selector.rb', line 70
def set_shard(shard, &block) klass = [:class_name]&.constantize || ActiveRecord::Base klass.connected_to(shard: shard.to_sym) do klass.prohibit_shard_swapping( .fetch(:lock, true), &block) end end