active_record_shards 4.0.0.beta8 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d318eea5c3e064fbc8abc478dbe78c3f173634e3dfb913727c212222c6aadaed
4
- data.tar.gz: ee3ccf1174544bbc076ce9470bf67ead36f26e44234368fe6e75a23ba1fbe3f4
3
+ metadata.gz: aa6b8faea89614322485e584a2e63f9cb7b6ee505c641c68dcf239337776230a
4
+ data.tar.gz: eb5038c548eecf373a19e811d0354df3c535b6f6f9bfa5cca9140e6d4dbe2994
5
5
  SHA512:
6
- metadata.gz: cf3e9bfff048f08174f36e2d36811975ff18ed983b018d04e2baa68ee3df8d9da146f9106582583d720c30c98420b38fb85b075562a7746456bafdeefc6110f9
7
- data.tar.gz: ca0a7afd7e2fc3e3d6083da8da213b61c5d98c669da3728bf7111e7e054d5d7aa6fb6620b851e8781b8c36db7b746503f171116cb54030f2f715242637ecc5c6
6
+ metadata.gz: 3b06434d4f484e2d8ea3cceaa98e535712c41b7ac9b2fece389ca25a21e1d0f6249b5c4e85a6206b8718784b9150477b26247de8f667439486dab8d0abf4ef30
7
+ data.tar.gz: 6453444d52019b1f296df12d96085abaabc40af5bf7595ed2077104efcec8bc7dcda7d43164efb254d09922c67690584e68f6c711d74cefe6de4d16fbe390bab
data/README.md CHANGED
@@ -1,11 +1,22 @@
1
- [![Build Status](https://secure.travis-ci.org/zendesk/active_record_shards.png)](http://travis-ci.org/zendesk/active_record_shards)
1
+ [![Build Status](https://github.com/zendesk/active_record_shards/workflows/CI/badge.svg)](https://github.com/zendesk/active_record_shards/actions?query=workflow%3ACI)
2
2
 
3
3
  # ActiveRecord Shards
4
4
 
5
- ActiveRecord Shards is an extension for ActiveRecord that provides support for sharded database and slaves. Basically it is just a nice way to
5
+ ActiveRecord Shards is an extension for ActiveRecord that provides support for sharded database and replicas. Basically it is just a nice way to
6
6
  switch between database connections. We've made the implementation very small, and have tried not to reinvent any wheels already present in ActiveRecord.
7
7
 
8
- ActiveRecord Shards has been used and tested on Rails 5.0 and has in some form or another been used in production on a large Rails app for several years.
8
+ ActiveRecord Shards has been used and tested on Rails 5.x and 6.0, and has in some form or another been used in production on large Rails apps for several years.
9
+
10
+ Rails 6.1 introduced new connection handling and support for sharding. Apps are encouraged to migrate to the native sharding logic but ActiveRecord Shards supports Rails 6.1 when `legacy_connection_handling` is set to `true`. For more information see [Rails 6.1 installation](#rails-61-installation) and Rails' [multiple databases guide](https://guides.rubyonrails.org/active_record_multiple_databases.html).
11
+
12
+ - [Installation](#installation)
13
+ - [Configuration](#configuration)
14
+ - [Migrations](#migrations)
15
+ - [Example](#example)
16
+ - [Shared Model](#create-a-table-for-the-shared-not-sharded-model)
17
+ - [Sharded Model](#create-a-table-for-the-sharded-model)
18
+ - [Usage](#usage)
19
+ - [Debugging](#debugging)
9
20
 
10
21
  ## Installation
11
22
 
@@ -13,85 +24,161 @@ ActiveRecord Shards has been used and tested on Rails 5.0 and has in some form o
13
24
 
14
25
  and make sure to require 'active\_record\_shards' in some way.
15
26
 
27
+ ### Rails 6.1 installation
28
+
29
+ Rails 6.1 is **only** supported with `legacy_connection_handling` set to `true`.
30
+
31
+ Enable the legacy handling in your configuration files e.g. `config/application.rb` by setting:
32
+
33
+ ``` Ruby
34
+ config.active_record.legacy_connection_handling = true
35
+ ```
36
+
37
+ or
38
+
39
+ ``` Ruby
40
+ ActiveRecord::Base.legacy_connection_handling = true
41
+ ```
42
+
16
43
  ## Configuration
17
44
 
18
- Add the slave and shard configuration to config/database.yml:
19
-
20
- production:
21
- adapter: mysql
22
- encoding: utf8
23
- database: my_app_main
24
- pool: 5
25
- host: db1
26
- username: root
27
- password:
28
- slave:
29
- host: db1_slave
30
- shards:
31
- 1:
32
- host: db_shard1
33
- database: my_app_shard
34
- slave:
35
- host: db_shard1_slave
36
- 2:
37
- host: db_shard2
38
- database: my_app_shard
39
- slave:
40
- host: db_shard2_slave
45
+ Add the replica and shard configuration to config/database.yml:
46
+
47
+ ```yaml
48
+ production:
49
+ adapter: mysql
50
+ encoding: utf8
51
+ database: my_app_main
52
+ pool: 5
53
+ host: db1
54
+ username: root
55
+ password:
56
+ replica:
57
+ host: db1_replica
58
+ shards:
59
+ 1:
60
+ host: db_shard1
61
+ database: my_app_shard
62
+ replica:
63
+ host: db_shard1_replica
64
+ 2:
65
+ host: db_shard2
66
+ database: my_app_shard
67
+ replica:
68
+ host: db_shard2_replica
69
+ ```
41
70
 
42
71
  basically connections inherit configuration from the parent configuration file.
43
72
 
44
- ## Usage
73
+ ## Migrations
45
74
 
46
- Normally you have some models that live on a shared database, and you might need to query this data in order to know what shard to switch to.
47
- All the models that live on the sharded database must inherit from ActiveRecordShards::ShardedModel:
75
+ ActiveRecord Shards also patches migrations to support running migrations on a shared (not sharded) or a sharded database.
76
+ Each migration class has to specify a shard spec indicating where to run the migration.
77
+
78
+ Valid shard specs:
79
+
80
+ * `:none` - Run this migration on the shared database, not any shards
81
+ * `:all` - Run this migration on all of the shards, not the shared database
82
+
83
+ #### Example
48
84
 
49
- class Account < ActiveRecord::Base
50
- has_many :projects
85
+ ###### Create a table for the shared (not sharded) model
86
+
87
+ ```ruby
88
+ class CreateAccounts < ActiveRecord::Migration
89
+ shard :none
90
+
91
+ def change
92
+ create_table :accounts do |t|
93
+ # This is NOT necessary for the gem to work, we just use it in the examples below demonstrating one way to switch shards
94
+ t.integer :shard_id, null: false
95
+
96
+ t.string :name
51
97
  end
98
+ end
99
+ end
100
+ ```
101
+
102
+ ###### Create a table for the sharded model
52
103
 
53
- class Project < ActiveRecordShards::ShardedModel
54
- belongs_to :account
104
+ ```ruby
105
+ class CreateProjects < ActiveRecord::Migration
106
+ shard :all
107
+
108
+ def change
109
+ create_table :projects do |t|
110
+ t.references :account
111
+ t.string :name
55
112
  end
113
+ end
114
+ end
115
+ ```
116
+
117
+ ## Usage
118
+
119
+ Normally you have some models that live on a shared database, and you might need to query this data in order to know what shard to switch to.
120
+ All the models that live on the shared database must be marked as not\_sharded:
121
+
122
+ ```ruby
123
+ class Account < ActiveRecord::Base
124
+ not_sharded
125
+
126
+ has_many :projects
127
+ end
128
+
129
+ class Project < ActiveRecord::Base
130
+ belongs_to :account
131
+ end
132
+ ```
56
133
 
57
134
  So in this setup the accounts live on the shared database, but the projects are sharded. If accounts have a shard\_id column, you could lookup the account
58
135
  in a rack middleware and switch to the right shard:
59
136
 
60
- class AccountMiddleware
61
- def initialize(app)
62
- @app = app
63
- end
64
-
65
- def call(env)
66
- account = lookup_account(env)
137
+ ```ruby
138
+ class AccountMiddleware
139
+ def initialize(app)
140
+ @app = app
141
+ end
67
142
 
68
- if account
69
- ActiveRecord::Base.on_shard(account.shard_id) do
70
- @app.call(env)
71
- end
72
- else
73
- @app.call(env)
74
- end
75
- end
143
+ def call(env)
144
+ account = lookup_account(env)
76
145
 
77
- def lookup_account(env)
78
- ...
146
+ if account
147
+ ActiveRecord::Base.on_shard(account.shard_id) do
148
+ @app.call(env)
79
149
  end
150
+ else
151
+ @app.call(env)
80
152
  end
153
+ end
81
154
 
82
- You can switch to the slave databases at any point by wrapping your code in an on\_slave block:
155
+ def lookup_account(env)
156
+ # ...
157
+ end
158
+ end
159
+ ```
83
160
 
84
- ActiveRecord::Base.on_slave do
85
- Account.find_by_big_expensive_query
86
- end
161
+ You can switch to the replica databases at any point by wrapping your code in an on\_replica block:
162
+
163
+ ```ruby
164
+ ActiveRecord::Base.on_replica do
165
+ Account.find_by_big_expensive_query
166
+ end
167
+ ```
168
+
169
+ This will perform the query on the replica, and mark the returned instances as read-only. There is also a shortcut for this:
170
+
171
+ ```ruby
172
+ Account.on_replica.find_by_big_expensive_query
173
+ ```
87
174
 
88
- This will perform the query on the slave, and mark the returned instances as read only. There is also a shortcut for this:
175
+ If you do not want instances returned from replicas to be marked as read-only, this can be disabled globally:
89
176
 
90
- Account.on_slave.find_by_big_expensive_query
177
+ `ActiveRecordShards.disable_replica_readonly_records = true`
91
178
 
92
179
  ## Debugging
93
180
 
94
- Show if a query went to master or slave in the logs:
181
+ Show if a query went to primary or replica in the logs:
95
182
 
96
183
  ```Ruby
97
184
  require 'active_record_shards/sql_comments'
@@ -1,40 +1,42 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module ActiveRecordShards
3
4
  module AssociationCollectionConnectionSelection
4
- def on_slave_if(condition)
5
- condition ? on_slave : self
5
+ def on_replica_if(condition)
6
+ condition ? on_replica : self
6
7
  end
7
8
 
8
- def on_slave_unless(condition)
9
- on_slave_if(!condition)
9
+ def on_replica_unless(condition)
10
+ on_replica_if(!condition)
10
11
  end
11
12
 
12
- def on_master_if(condition)
13
- condition ? on_master : self
13
+ def on_primary_if(condition)
14
+ condition ? on_primary : self
14
15
  end
15
16
 
16
- def on_master_unless(condition)
17
- on_master_if(!condition)
17
+ def on_primary_unless(condition)
18
+ on_primary_if(!condition)
18
19
  end
19
20
 
20
- def on_slave
21
- MasterSlaveProxy.new(self, :slave)
21
+ def on_replica
22
+ PrimaryReplicaProxy.new(self, :replica)
22
23
  end
23
24
 
24
- def on_master
25
- MasterSlaveProxy.new(self, :master)
25
+ def on_primary
26
+ PrimaryReplicaProxy.new(self, :primary)
26
27
  end
27
28
 
28
- class MasterSlaveProxy
29
+ class PrimaryReplicaProxy
29
30
  def initialize(association_collection, which)
30
31
  @association_collection = association_collection
31
32
  @which = which
32
33
  end
33
34
 
34
- def method_missing(method, *args, &block) # rubocop:disable Style/MethodMissing
35
+ def method_missing(method, *args, &block) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
35
36
  reflection = @association_collection.proxy_association.reflection
36
37
  reflection.klass.on_cx_switch_block(@which) { @association_collection.send(method, *args, &block) }
37
38
  end
39
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
38
40
  end
39
41
  end
40
42
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'active_support/core_ext'
3
4
 
4
5
  module ActiveRecordShards
@@ -6,7 +7,7 @@ module ActiveRecordShards
6
7
  module_function
7
8
 
8
9
  def explode(conf)
9
- conf = conf.deep_dup
10
+ conf = conf.to_h.deep_dup
10
11
 
11
12
  conf.to_a.each do |env_name, env_config|
12
13
  next unless shards = env_config.delete('shards')
@@ -23,9 +24,9 @@ module ActiveRecordShards
23
24
  end
24
25
 
25
26
  conf.to_a.each do |env_name, env_config|
26
- if slave_conf = env_config.delete('slave')
27
- expand_child!(env_config, slave_conf)
28
- conf["#{env_name}_slave"] = slave_conf
27
+ if replica_conf = env_config.delete('replica')
28
+ expand_child!(env_config, replica_conf)
29
+ conf["#{env_name}_replica"] = replica_conf
29
30
  end
30
31
  end
31
32
 
@@ -34,7 +35,7 @@ module ActiveRecordShards
34
35
 
35
36
  def expand_child!(parent, child)
36
37
  parent.each do |key, value|
37
- unless ['slave', 'shards'].include?(key) || value.is_a?(Hash)
38
+ unless ['replica', 'shards'].include?(key) || value.is_a?(Hash)
38
39
  child[key] ||= value
39
40
  end
40
41
  end
@@ -1,5 +1,15 @@
1
1
  module ActiveRecordShards
2
- module BaseConfig
2
+ module ConnectionSwitcher
3
+ def connection_specification_name
4
+ name = current_shard_selection.resolve_connection_name(sharded: is_sharded?, configurations: configurations)
5
+
6
+ unless configurations[name] || name == "primary"
7
+ raise ActiveRecord::AdapterNotSpecified, "No database defined by #{name} in your database config. (configurations: #{configurations.to_h.keys.inspect})"
8
+ end
9
+
10
+ name
11
+ end
12
+
3
13
  private
4
14
 
5
15
  def ensure_shard_connection
@@ -0,0 +1,30 @@
1
+ module ActiveRecordShards
2
+ module ConnectionSwitcher
3
+ def connection_specification_name
4
+ name = current_shard_selection.resolve_connection_name(sharded: is_sharded?, configurations: configurations)
5
+
6
+ @_ars_connection_specification_names ||= {}
7
+ unless @_ars_connection_specification_names.include?(name)
8
+ unless configurations[name] || name == "primary"
9
+ raise ActiveRecord::AdapterNotSpecified, "No database defined by #{name} in your database config. (configurations: #{configurations.to_h.keys.inspect})"
10
+ end
11
+
12
+ @_ars_connection_specification_names[name] = true
13
+ end
14
+
15
+ name
16
+ end
17
+
18
+ private
19
+
20
+ def ensure_shard_connection
21
+ # See if we've connected before. If not, call `#establish_connection`
22
+ # so that ActiveRecord can resolve connection_specification_name to an
23
+ # ARS connection.
24
+ spec_name = connection_specification_name
25
+
26
+ pool = connection_handler.retrieve_connection_pool(spec_name)
27
+ connection_handler.establish_connection(spec_name.to_sym) if pool.nil?
28
+ end
29
+ end
30
+ end
@@ -1,9 +1,14 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'active_record_shards/shard_support'
3
4
 
4
5
  module ActiveRecordShards
5
6
  module ConnectionSwitcher
6
- SHARD_NAMES_CONFIG_KEY = 'shard_names'.freeze
7
+ if "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}" == '6.1'
8
+ SHARD_NAMES_CONFIG_KEY = :shard_names
9
+ else
10
+ SHARD_NAMES_CONFIG_KEY = 'shard_names'
11
+ end
7
12
 
8
13
  def self.extended(base)
9
14
  base.singleton_class.send(:alias_method, :load_schema_without_default_shard!, :load_schema!)
@@ -13,17 +18,21 @@ module ActiveRecordShards
13
18
  base.singleton_class.send(:alias_method, :table_exists?, :table_exists_with_default_shard?)
14
19
  end
15
20
 
21
+ def on_primary_db(&block)
22
+ on_shard(nil, &block)
23
+ end
24
+
16
25
  def on_shard(shard)
17
- old_selection = current_shard_selection
18
- switch_connection(ShardSelection.new(shard)) if supports_sharding?
26
+ old_options = current_shard_selection.options
27
+ switch_connection(shard: shard) if supports_sharding?
19
28
  yield
20
29
  ensure
21
- switch_connection(old_selection)
30
+ switch_connection(old_options)
22
31
  end
23
32
 
24
- def on_first_shard
33
+ def on_first_shard(&block)
25
34
  shard_name = shard_names.first
26
- on_shard(shard_name) { yield }
35
+ on_shard(shard_name, &block)
27
36
  end
28
37
 
29
38
  def shards
@@ -31,85 +40,144 @@ module ActiveRecordShards
31
40
  end
32
41
 
33
42
  def on_all_shards
34
- old_selection = current_shard_selection
43
+ old_options = current_shard_selection.options
35
44
  if supports_sharding?
36
45
  shard_names.map do |shard|
37
- switch_connection(ShardSelection.new(shard))
46
+ switch_connection(shard: shard)
38
47
  yield(shard)
39
48
  end
40
49
  else
41
50
  [yield]
42
51
  end
43
52
  ensure
44
- switch_connection(old_selection)
53
+ switch_connection(old_options)
54
+ end
55
+
56
+ def on_replica_if(condition, &block)
57
+ condition ? on_replica(&block) : yield
58
+ end
59
+
60
+ def on_replica_unless(condition, &block)
61
+ on_replica_if(!condition, &block)
62
+ end
63
+
64
+ def on_primary_if(condition, &block)
65
+ condition ? on_primary(&block) : yield
45
66
  end
46
67
 
47
- def connection_config
48
- super.merge(current_shard_selection.connection_config.merge(sharded: is_sharded?))
68
+ def on_primary_unless(condition, &block)
69
+ on_primary_if(!condition, &block)
70
+ end
71
+
72
+ def on_primary_or_replica(which, &block)
73
+ if block_given?
74
+ on_cx_switch_block(which, &block)
75
+ else
76
+ PrimaryReplicaProxy.new(self, which)
77
+ end
78
+ end
79
+
80
+ # Executes queries using the replica database. Fails over to primary if no replica is found.
81
+ # if you want to execute a block of code on the replica you can go:
82
+ # Account.on_replica do
83
+ # Account.first
84
+ # end
85
+ # the first account will be found on the replica DB
86
+ #
87
+ # For one-liners you can simply do
88
+ # Account.on_replica.first
89
+ def on_replica(&block)
90
+ on_primary_or_replica(:replica, &block)
91
+ end
92
+
93
+ def on_primary(&block)
94
+ on_primary_or_replica(:primary, &block)
95
+ end
96
+
97
+ def on_cx_switch_block(which, force: false, construct_ro_scope: nil, &block)
98
+ @disallow_replica ||= 0
99
+ @disallow_replica += 1 if which == :primary
100
+
101
+ switch_to_replica = force || @disallow_replica.zero?
102
+ old_options = current_shard_selection.options
103
+
104
+ switch_connection(replica: switch_to_replica)
105
+
106
+ # we avoid_readonly_scope to prevent some stack overflow problems, like when
107
+ # .columns calls .with_scope which calls .columns and onward, endlessly.
108
+ if self == ActiveRecord::Base || !switch_to_replica || construct_ro_scope == false || ActiveRecordShards.disable_replica_readonly_records == true
109
+ yield
110
+ else
111
+ readonly.scoping(&block)
112
+ end
113
+ ensure
114
+ @disallow_replica -= 1 if which == :primary
115
+ switch_connection(old_options) if old_options
49
116
  end
50
117
 
51
118
  def supports_sharding?
52
119
  shard_names.any?
53
120
  end
54
121
 
55
- def current_shard_selection
56
- Thread.current[:shard_selection] ||= NoShardSelection.new
122
+ def on_replica?
123
+ current_shard_selection.on_replica?
57
124
  end
58
125
 
59
- def current_shard_selection=(shard_selection)
60
- Thread.current[:shard_selection] = shard_selection
126
+ def current_shard_selection
127
+ Thread.current[:shard_selection] ||= ShardSelection.new
61
128
  end
62
129
 
63
130
  def current_shard_id
64
131
  current_shard_selection.shard
65
132
  end
66
133
 
67
- def on_shard?
68
- current_shard_selection.on_shard?
69
- end
70
-
71
134
  def shard_names
72
- unless config = configurations[shard_env]
73
- raise "Did not find #{shard_env} in configurations, did you forget to add it to your database config? (configurations: #{configurations.inspect})"
135
+ unless config_for_env.fetch(SHARD_NAMES_CONFIG_KEY, []).all? { |shard_name| shard_name.is_a?(Integer) }
136
+ raise "All shard names must be integers: #{config_for_env[SHARD_NAMES_CONFIG_KEY].inspect}."
74
137
  end
75
- unless config[SHARD_NAMES_CONFIG_KEY]
76
- raise "No shards configured for #{shard_env}"
77
- end
78
- unless config[SHARD_NAMES_CONFIG_KEY].all? { |shard_name| shard_name.is_a?(Integer) }
79
- raise "All shard names must be integers: #{config[SHARD_NAMES_CONFIG_KEY].inspect}."
80
- end
81
- config[SHARD_NAMES_CONFIG_KEY]
82
- end
83
138
 
84
- def table_exists_with_default_shard?
85
- with_default_shard { table_exists_without_default_shard? }
139
+ config_for_env[SHARD_NAMES_CONFIG_KEY] || []
86
140
  end
87
141
 
88
142
  private
89
143
 
90
- def switch_connection(selection)
91
- if selection.is_a?(ShardSelection)
144
+ def config_for_env
145
+ @_ars_config_for_env ||= {}
146
+ @_ars_config_for_env[shard_env] ||= begin
92
147
  unless config = configurations[shard_env]
93
- raise "Did not find #{shard_env} in configurations, did you forget to add it to your database config? (configurations: #{configurations.inspect})"
148
+ raise "Did not find #{shard_env} in configurations, did you forget to add it to your database config? (configurations: #{configurations.to_h.keys.inspect})"
149
+ end
150
+
151
+ config
152
+ end
153
+ end
154
+ alias_method :check_config_for_env, :config_for_env
155
+
156
+ def switch_connection(options)
157
+ if options.any?
158
+ if options.key?(:replica)
159
+ current_shard_selection.on_replica = options[:replica]
94
160
  end
95
- unless config['shard_names'].include?(selection.shard)
96
- raise "Did not find shard #{selection.shard} in configurations"
161
+
162
+ if options.key?(:shard)
163
+ check_config_for_env
164
+
165
+ current_shard_selection.shard = options[:shard]
97
166
  end
98
- self.current_shard_selection = selection
99
167
 
100
168
  ensure_shard_connection
101
- else
102
- self.current_shard_selection = selection
103
169
  end
104
170
  end
105
171
 
106
172
  def shard_env
107
- ActiveRecordShards.rails_env
173
+ ActiveRecordShards.app_env
108
174
  end
109
175
 
110
- def with_default_shard
111
- if is_sharded? && !on_shard? && table_name != ActiveRecord::SchemaMigration.table_name
112
- on_first_shard { yield }
176
+ # Make these few schema related methods available before having switched to
177
+ # a shard.
178
+ def with_default_shard(&block)
179
+ if is_sharded? && current_shard_id.nil? && table_name != ActiveRecord::SchemaMigration.table_name
180
+ on_first_shard(&block)
113
181
  else
114
182
  yield
115
183
  end
@@ -118,14 +186,30 @@ module ActiveRecordShards
118
186
  def load_schema_with_default_shard!
119
187
  with_default_shard { load_schema_without_default_shard! }
120
188
  end
189
+
190
+ def table_exists_with_default_shard?
191
+ with_default_shard { table_exists_without_default_shard? }
192
+ end
193
+
194
+ class PrimaryReplicaProxy
195
+ def initialize(target, which)
196
+ @target = target
197
+ @which = which
198
+ end
199
+
200
+ def method_missing(method, *args, &block) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
201
+ @target.on_primary_or_replica(@which) { @target.send(method, *args, &block) }
202
+ end
203
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
204
+ end
121
205
  end
122
206
  end
123
207
 
124
208
  case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
125
- when '5.0'
126
- require 'active_record_shards/connection_switcher_5_0'
127
209
  when '5.1', '5.2'
128
- require 'active_record_shards/connection_switcher_5_1'
210
+ require 'active_record_shards/connection_switcher-5-1'
211
+ when '6.0', '6.1'
212
+ require 'active_record_shards/connection_switcher-6-0'
129
213
  else
130
214
  raise "ActiveRecordShards is not compatible with #{ActiveRecord::VERSION::STRING}"
131
215
  end