Class: ActiveRecord::Middleware::ShardSelector

Inherits:
Object
  • Object
show all
Defined in:
lib/active_record/middleware/shard_selector.rb

Overview

Shard Selector Middleware

The ShardSelector 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. If lock 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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, resolver, options = {}) ⇒ ShardSelector

Returns a new instance of ShardSelector.



47
48
49
50
51
# File 'lib/active_record/middleware/shard_selector.rb', line 47

def initialize(app, resolver, options = {})
  @app = app
  @resolver = resolver
  @options = options
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



53
54
55
# File 'lib/active_record/middleware/shard_selector.rb', line 53

def options
  @options
end

#resolverObject (readonly)

Returns the value of attribute resolver.



53
54
55
# File 'lib/active_record/middleware/shard_selector.rb', line 53

def resolver
  @resolver
end

Instance Method Details

#call(env) ⇒ Object



55
56
57
58
59
60
61
62
63
# File '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