active_record_slave 1.2.1 → 1.3.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 +4 -4
- data/README.md +122 -84
- data/Rakefile +16 -13
- data/lib/active_record_slave/active_record_slave.rb +8 -10
- data/lib/active_record_slave/instance_methods.rb +5 -8
- data/lib/active_record_slave/railtie.rb +1 -1
- data/lib/active_record_slave/version.rb +1 -1
- data/test/active_record_slave_test.rb +13 -13
- data/test/test.sqlite3 +0 -0
- data/test/test_helper.rb +1 -5
- data/test/test_slave.sqlite3 +0 -0
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df85e9044445ca044fcbe373312c3634f5c4d1f5
|
4
|
+
data.tar.gz: 1d31ecdaa29211fa71f852a95ab183498a26a0fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe6e8c3dfa5e7638879c954e016b6970e4432865b0a9e60e8f0d769b2201b62c571e5bda9e222770c7839f1d5884b689b0de6980b13c95290096a07572d6f94b
|
7
|
+
data.tar.gz: 38475bf316504c120a18cd7aa0e355e431dd99842370e79c1a7cb37ceaf67e48c26694e4bfc2d8c9a1339cb50a3d41313cd27c86066f16a3149969b4f02977ec
|
data/README.md
CHANGED
@@ -1,38 +1,43 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# active_record_slave
|
2
|
+
[](https://rubygems.org/gems/active_record_slave) [](https://travis-ci.org/rocketjob/active_record_slave) [](https://rubygems.org/gems/active_record_slave)  [-Support-brightgreen.svg)](https://gitter.im/rocketjob/support)
|
3
3
|
|
4
|
-
ActiveRecord
|
4
|
+
Redirect ActiveRecord (Rails) reads to slave databases while ensuring all writes go to the master database.
|
5
5
|
|
6
|
-
*
|
6
|
+
* https://github.com/rocketjob/active_record_slave
|
7
7
|
|
8
8
|
## Introduction
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
any reads that are performed in a transaction will always go to the master
|
10
|
+
Redirect database reads to slave instances while ensuring that all writes go to the master database.
|
11
|
+
Any reads that are performed within a database transaction are by default directed to the master
|
13
12
|
database to ensure data consistency.
|
14
13
|
|
14
|
+
## Status
|
15
|
+
|
16
|
+
Production Ready. Actively used in large production environments.
|
17
|
+
|
15
18
|
## Features
|
16
19
|
|
17
|
-
*
|
18
|
-
* Works with any database driver that works with ActiveRecord
|
19
|
-
* Supports all Rails 3
|
20
|
-
*
|
21
|
-
|
22
|
-
*
|
23
|
-
*
|
24
|
-
*
|
25
|
-
*
|
20
|
+
* Redirect reads to a single slave database.
|
21
|
+
* Works with any database driver that works with ActiveRecord.
|
22
|
+
* Supports all Rails 3, 4, or 5 read apis.
|
23
|
+
* Including dynamic finders, AREL, and ActiveRecord::Base.select.
|
24
|
+
* Transaction aware
|
25
|
+
* Detects when a query is inside of a transaction and sends those reads to the master by default.
|
26
|
+
* Can be configured to send reads in a transaction to slave databases.
|
27
|
+
* Lightweight footprint.
|
28
|
+
* No overhead whatsoever when a slave is not configured.
|
29
|
+
* Negligible overhead when redirecting reads to the slave.
|
30
|
+
* Connection Pools to both databases are retained and maintained independently by ActiveRecord.
|
26
31
|
* The master and slave databases do not have to be of the same type.
|
27
|
-
|
28
|
-
* Debug logs include a prefix of
|
29
|
-
to the slave database
|
32
|
+
* For example Oracle could be the master with MySQL as the slave database.
|
33
|
+
* Debug logs include a prefix of `Slave: ` to indicate which SQL statements are going
|
34
|
+
to the slave database.
|
30
35
|
|
31
36
|
### Example showing Slave redirected read
|
32
37
|
|
33
38
|
```ruby
|
34
39
|
# Read from the slave database
|
35
|
-
r = Role.where(:
|
40
|
+
r = Role.where(name: 'manager').first
|
36
41
|
r.description = 'Manager'
|
37
42
|
|
38
43
|
# Save changes back to the master database
|
@@ -48,7 +53,7 @@ Log file output:
|
|
48
53
|
|
49
54
|
```ruby
|
50
55
|
Role.transaction do
|
51
|
-
r = Role.where(:
|
56
|
+
r = Role.where(name: 'manager').first
|
52
57
|
r.description = 'Manager'
|
53
58
|
r.save!
|
54
59
|
end
|
@@ -65,7 +70,7 @@ Sometimes it is necessary to read from the master:
|
|
65
70
|
|
66
71
|
```ruby
|
67
72
|
ActiveRecordSlave.read_from_master do
|
68
|
-
r = Role.where(:
|
73
|
+
r = Role.where(name: 'manager').first
|
69
74
|
end
|
70
75
|
```
|
71
76
|
|
@@ -96,9 +101,6 @@ D, [2012-11-06T19:43:26.892697 #89002] DEBUG -- : (0.9ms) commit transaction
|
|
96
101
|
By default ActiveRecordSlave detects when a call is inside a transaction and will
|
97
102
|
send all reads to the _master_ when a transaction is active.
|
98
103
|
|
99
|
-
With the latest Rails releases, Rails automatically wraps all Controller Action
|
100
|
-
calls with a transaction, effectively sending all reads to the master database.
|
101
|
-
|
102
104
|
It is now possible to send reads to database slaves and ignore whether currently
|
103
105
|
inside a transaction:
|
104
106
|
|
@@ -114,22 +116,19 @@ able to read any changes already part of the transaction, but not yet committed
|
|
114
116
|
and wrap those reads with `ActiveRecordSlave.read_from_master`
|
115
117
|
|
116
118
|
```ruby
|
117
|
-
|
118
|
-
|
119
|
+
Inquiry.transaction do
|
120
|
+
# Create a new inquiry
|
121
|
+
Inquiry.create
|
122
|
+
|
123
|
+
# The above inquiry is not visible yet if already in a Rails transaction.
|
124
|
+
# Use `read_from_master` to ensure it is included in the count below:
|
125
|
+
ActiveRecordSlave.read_from_master do
|
126
|
+
count = Inquiry.count
|
127
|
+
end
|
119
128
|
|
120
|
-
# Then make sure that the new inquiry that is not yet committed is visible during
|
121
|
-
# the read below:
|
122
|
-
ActiveRecordSlave.read_from_master do
|
123
|
-
count = Inquiry.count
|
124
129
|
end
|
125
130
|
```
|
126
131
|
|
127
|
-
## Dependencies
|
128
|
-
|
129
|
-
* Tested on Rails 3 and Rails 4
|
130
|
-
|
131
|
-
See [.travis.yml](https://github.com/reidmorrison/active_record_slave/.travis.yml) for the list of tested Ruby platforms
|
132
|
-
|
133
132
|
## Note
|
134
133
|
|
135
134
|
ActiveRecord::Base.execute is sometimes used to perform custom SQL calls against
|
@@ -142,7 +141,23 @@ which we do not want redirected to the slave
|
|
142
141
|
|
143
142
|
## Install
|
144
143
|
|
145
|
-
|
144
|
+
Add to `Gemfile`
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
gem 'active_record_slave'
|
148
|
+
```
|
149
|
+
|
150
|
+
Run bundler to install:
|
151
|
+
|
152
|
+
```
|
153
|
+
bundle
|
154
|
+
```
|
155
|
+
|
156
|
+
Or, without Bundler:
|
157
|
+
|
158
|
+
```
|
159
|
+
gem install active_record_slave
|
160
|
+
```
|
146
161
|
|
147
162
|
## Configuration
|
148
163
|
|
@@ -152,80 +167,103 @@ along with all the usual ActiveRecord database configuration options.
|
|
152
167
|
For Example:
|
153
168
|
|
154
169
|
```yaml
|
155
|
-
|
156
|
-
database:
|
157
|
-
username:
|
158
|
-
password:
|
170
|
+
production:
|
171
|
+
database: production
|
172
|
+
username: username
|
173
|
+
password: password
|
159
174
|
encoding: utf8
|
160
175
|
adapter: mysql
|
161
|
-
host:
|
162
|
-
pool:
|
176
|
+
host: master1
|
177
|
+
pool: 50
|
163
178
|
slave:
|
164
|
-
database:
|
165
|
-
username:
|
166
|
-
password:
|
179
|
+
database: production
|
180
|
+
username: username
|
181
|
+
password: password
|
167
182
|
encoding: utf8
|
168
183
|
adapter: mysql
|
169
|
-
host:
|
170
|
-
pool:
|
184
|
+
host: slave1
|
185
|
+
pool: 50
|
171
186
|
```
|
172
187
|
|
173
188
|
Sometimes it is useful to turn on slave reads per host, for example to activate
|
174
189
|
slave reads only on the linux host 'batch':
|
175
190
|
|
176
191
|
```yaml
|
177
|
-
|
178
|
-
database:
|
179
|
-
username:
|
180
|
-
password:
|
192
|
+
production:
|
193
|
+
database: production
|
194
|
+
username: username
|
195
|
+
password: password
|
181
196
|
encoding: utf8
|
182
197
|
adapter: mysql
|
183
|
-
host:
|
184
|
-
pool:
|
198
|
+
host: master1
|
199
|
+
pool: 50
|
185
200
|
<% if `hostname`.strip == 'batch' %>
|
186
201
|
slave:
|
187
|
-
database:
|
188
|
-
username:
|
189
|
-
password:
|
202
|
+
database: production
|
203
|
+
username: username
|
204
|
+
password: password
|
190
205
|
encoding: utf8
|
191
206
|
adapter: mysql
|
192
|
-
host:
|
193
|
-
pool:
|
207
|
+
host: slave1
|
208
|
+
pool: 50
|
194
209
|
<% end %>
|
195
210
|
```
|
196
211
|
|
197
|
-
|
212
|
+
If there are multiple slaves, it is possible to randomly select a slave on startup
|
213
|
+
to balance the load across the slaves:
|
198
214
|
|
199
|
-
|
215
|
+
```yaml
|
216
|
+
production:
|
217
|
+
database: production
|
218
|
+
username: username
|
219
|
+
password: password
|
220
|
+
encoding: utf8
|
221
|
+
adapter: mysql
|
222
|
+
host: master1
|
223
|
+
pool: 50
|
224
|
+
slave:
|
225
|
+
database: production
|
226
|
+
username: username
|
227
|
+
password: password
|
228
|
+
encoding: utf8
|
229
|
+
adapter: mysql
|
230
|
+
host: <%= %w(slave1 slave2 slave3).sample %>
|
231
|
+
pool: 50
|
232
|
+
```
|
200
233
|
|
201
|
-
|
202
|
-
----
|
234
|
+
Slaves can also be assigned to specific hosts by using the hostname:
|
203
235
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
236
|
+
```yaml
|
237
|
+
production:
|
238
|
+
database: production
|
239
|
+
username: username
|
240
|
+
password: password
|
241
|
+
encoding: utf8
|
242
|
+
adapter: mysql
|
243
|
+
host: master1
|
244
|
+
pool: 50
|
245
|
+
slave:
|
246
|
+
database: production
|
247
|
+
username: username
|
248
|
+
password: password
|
249
|
+
encoding: utf8
|
250
|
+
adapter: mysql
|
251
|
+
host: <%= `hostname`.strip == 'app1' ? 'slave1' : 'slave2' %>
|
252
|
+
pool: 50
|
253
|
+
```
|
208
254
|
|
209
|
-
|
255
|
+
## Dependencies
|
210
256
|
|
211
|
-
|
212
|
-
-------
|
257
|
+
See [.travis.yml](https://github.com/reidmorrison/active_record_slave/blob/master/.travis.yml) for the list of tested Ruby platforms
|
213
258
|
|
214
|
-
|
259
|
+
## Possible Future Enhancements
|
215
260
|
|
216
|
-
|
217
|
-
-------
|
261
|
+
* Support for multiple named slaves (ask for it by submitting an issue)
|
218
262
|
|
219
|
-
|
263
|
+
## Versioning
|
220
264
|
|
221
|
-
|
222
|
-
you may not use this file except in compliance with the License.
|
223
|
-
You may obtain a copy of the License at
|
265
|
+
This project uses [Semantic Versioning](http://semver.org/).
|
224
266
|
|
225
|
-
|
267
|
+
## Author
|
226
268
|
|
227
|
-
|
228
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
229
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
230
|
-
See the License for the specific language governing permissions and
|
231
|
-
limitations under the License.
|
269
|
+
[Reid Morrison](https://github.com/reidmorrison) :: @reidmorrison
|
data/Rakefile
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
|
2
|
-
require '
|
1
|
+
# Setup bundler to avoid having to run bundle exec all the time.
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
3
4
|
|
4
|
-
|
5
|
-
|
5
|
+
require 'rake/testtask'
|
6
|
+
require_relative 'lib/active_record_slave/version'
|
6
7
|
|
7
8
|
task :gem do
|
8
9
|
system "gem build active_record_slave.gemspec"
|
@@ -15,14 +16,16 @@ task :publish => :gem do
|
|
15
16
|
system "rm active_record_slave-#{ActiveRecordSlave::VERSION}.gem"
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
t.verbose = true
|
23
|
-
end
|
24
|
-
|
25
|
-
Rake::Task['functional'].invoke
|
19
|
+
Rake::TestTask.new(:test) do |t|
|
20
|
+
t.pattern = 'test/**/*_test.rb'
|
21
|
+
t.verbose = true
|
22
|
+
t.warning = false
|
26
23
|
end
|
27
24
|
|
28
|
-
|
25
|
+
# By default run tests against all appraisals
|
26
|
+
if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
|
27
|
+
require 'appraisal'
|
28
|
+
task default: :appraisal
|
29
|
+
else
|
30
|
+
task default: :test
|
31
|
+
end
|
@@ -13,11 +13,12 @@ module ActiveRecordSlave
|
|
13
13
|
# In a non-Rails environment, supply the environment such as
|
14
14
|
# 'development', 'production'
|
15
15
|
def self.install!(adapter_class = nil, environment = nil)
|
16
|
-
slave_config =
|
17
|
-
ActiveRecord::Base.connection.config
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
slave_config =
|
17
|
+
if ActiveRecord::Base.connection.respond_to?(:config)
|
18
|
+
ActiveRecord::Base.connection.config[:slave]
|
19
|
+
else
|
20
|
+
ActiveRecord::Base.configurations[environment || Rails.env]['slave']
|
21
|
+
end
|
21
22
|
if slave_config
|
22
23
|
ActiveRecord::Base.logger.info "ActiveRecordSlave.install! v#{ActiveRecordSlave::VERSION} Establishing connection to slave database"
|
23
24
|
Slave.establish_connection(slave_config)
|
@@ -25,9 +26,6 @@ module ActiveRecordSlave
|
|
25
26
|
# Inject a new #select method into the ActiveRecord Database adapter
|
26
27
|
base = adapter_class || ActiveRecord::Base.connection.class
|
27
28
|
base.send(:include, InstanceMethods)
|
28
|
-
SELECT_METHODS.each do |select_method|
|
29
|
-
base.alias_method_chain(select_method, :slave_reader)
|
30
|
-
end
|
31
29
|
else
|
32
30
|
ActiveRecord::Base.logger.info "ActiveRecordSlave not installed since no slave database defined"
|
33
31
|
end
|
@@ -82,7 +80,7 @@ module ActiveRecordSlave
|
|
82
80
|
# Parameters
|
83
81
|
# variable [Symbol]
|
84
82
|
# Name of variable to get
|
85
|
-
if RUBY_VERSION.to_i >= 2
|
83
|
+
if (RUBY_VERSION.to_i >= 2) && !defined?(Rubinius::VERSION)
|
86
84
|
# Fibers have their own thread local variables so use thread_variable_get
|
87
85
|
def self.thread_variable_get(variable)
|
88
86
|
Thread.current.thread_variable_get(variable)
|
@@ -100,7 +98,7 @@ module ActiveRecordSlave
|
|
100
98
|
# Name of variable to set
|
101
99
|
# value [Object]
|
102
100
|
# Value to set the thread variable to
|
103
|
-
if RUBY_VERSION.to_i >= 2
|
101
|
+
if (RUBY_VERSION.to_i >= 2) && !defined?(Rubinius::VERSION)
|
104
102
|
# Fibers have their own thread local variables so use thread_variable_set
|
105
103
|
def self.thread_variable_set(variable, value)
|
106
104
|
Thread.current.thread_variable_set(variable, value)
|
@@ -11,14 +11,11 @@ module ActiveRecordSlave
|
|
11
11
|
# Database Adapter method #exec_query is called for every select call
|
12
12
|
# Replace #exec_query with one that calls the slave connection instead
|
13
13
|
eval <<-METHOD
|
14
|
-
def #{select_method}
|
15
|
-
if active_record_slave_read_from_master?
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
ActiveRecordSlave.read_from_master do
|
20
|
-
Slave.connection.#{select_method}(sql, "Slave: \#{name || 'SQL'}", *args)
|
21
|
-
end
|
14
|
+
def #{select_method}(sql, name = nil, *args)
|
15
|
+
return super if active_record_slave_read_from_master?
|
16
|
+
|
17
|
+
ActiveRecordSlave.read_from_master do
|
18
|
+
Slave.connection.#{select_method}(sql, "Slave: \#{name || 'SQL'}", *args)
|
22
19
|
end
|
23
20
|
end
|
24
21
|
METHOD
|
@@ -17,7 +17,7 @@ module ActiveRecordSlave #:nodoc:
|
|
17
17
|
config.active_record_slave = ::ActiveRecordSlave
|
18
18
|
|
19
19
|
# Initialize ActiveRecordSlave
|
20
|
-
initializer "load active_record_slave"
|
20
|
+
initializer "load active_record_slave", :after => "active_record.initialize_database" do
|
21
21
|
ActiveRecordSlave.install!
|
22
22
|
end
|
23
23
|
|
@@ -2,9 +2,9 @@ require File.join(File.dirname(__FILE__), 'test_helper')
|
|
2
2
|
require 'logger'
|
3
3
|
require 'erb'
|
4
4
|
|
5
|
-
l
|
6
|
-
l.level
|
7
|
-
ActiveRecord::Base.logger
|
5
|
+
l = Logger.new('test.log')
|
6
|
+
l.level = ::Logger::DEBUG
|
7
|
+
ActiveRecord::Base.logger = l
|
8
8
|
ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read('test/database.yml')).result)
|
9
9
|
|
10
10
|
# Define Schema in second database (slave)
|
@@ -42,9 +42,9 @@ ActiveRecordSlave.install!(nil, 'test')
|
|
42
42
|
# Unit Test for active_record_slave
|
43
43
|
#
|
44
44
|
class ActiveRecordSlaveTest < Minitest::Test
|
45
|
-
|
45
|
+
describe 'the active_record_slave gem' do
|
46
46
|
|
47
|
-
|
47
|
+
before do
|
48
48
|
ActiveRecordSlave.ignore_transactions = false
|
49
49
|
|
50
50
|
User.delete_all
|
@@ -52,16 +52,16 @@ class ActiveRecordSlaveTest < Minitest::Test
|
|
52
52
|
@name = "Joe Bloggs"
|
53
53
|
@address = "Somewhere"
|
54
54
|
@user = User.new(
|
55
|
-
:name
|
55
|
+
:name => @name,
|
56
56
|
:address => @address
|
57
57
|
)
|
58
58
|
end
|
59
59
|
|
60
|
-
|
60
|
+
after do
|
61
61
|
User.delete_all
|
62
62
|
end
|
63
63
|
|
64
|
-
|
64
|
+
it 'saves to master' do
|
65
65
|
assert_equal true, @user.save!
|
66
66
|
end
|
67
67
|
|
@@ -72,7 +72,7 @@ class ActiveRecordSlaveTest < Minitest::Test
|
|
72
72
|
# so the tests will be verifying that reads going to the "slave" (second)
|
73
73
|
# database do not find data written to the master.
|
74
74
|
#
|
75
|
-
|
75
|
+
it 'saves to master, read from slave' do
|
76
76
|
# Read from slave
|
77
77
|
assert_equal 0, User.where(:name => @name, :address => @address).count
|
78
78
|
|
@@ -83,7 +83,7 @@ class ActiveRecordSlaveTest < Minitest::Test
|
|
83
83
|
assert_equal 0, User.where(:name => @name, :address => @address).count
|
84
84
|
end
|
85
85
|
|
86
|
-
|
86
|
+
it 'save to master, read from master when in a transaction' do
|
87
87
|
assert_equal false, ActiveRecordSlave.ignore_transactions?
|
88
88
|
|
89
89
|
User.transaction do
|
@@ -104,7 +104,7 @@ class ActiveRecordSlaveTest < Minitest::Test
|
|
104
104
|
assert_equal 0, User.where(:name => @name, :address => @address).count
|
105
105
|
end
|
106
106
|
|
107
|
-
|
107
|
+
it 'save to master, read from slave when ignoring transactions' do
|
108
108
|
ActiveRecordSlave.ignore_transactions = true
|
109
109
|
assert_equal true, ActiveRecordSlave.ignore_transactions?
|
110
110
|
|
@@ -126,7 +126,7 @@ class ActiveRecordSlaveTest < Minitest::Test
|
|
126
126
|
assert_equal 0, User.where(:name => @name, :address => @address).count
|
127
127
|
end
|
128
128
|
|
129
|
-
|
129
|
+
it 'saves to master, force a read from master even when _not_ in a transaction' do
|
130
130
|
# Read from slave
|
131
131
|
assert_equal 0, User.where(:name => @name, :address => @address).count
|
132
132
|
|
@@ -143,4 +143,4 @@ class ActiveRecordSlaveTest < Minitest::Test
|
|
143
143
|
end
|
144
144
|
|
145
145
|
end
|
146
|
-
end
|
146
|
+
end
|
data/test/test.sqlite3
CHANGED
Binary file
|
data/test/test_helper.rb
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
-
# Allow test to be run in-place without requiring a gem install
|
2
|
-
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
3
|
-
|
4
|
-
# Configure Rails Environment
|
5
1
|
ENV['RAILS_ENV'] = 'test'
|
6
2
|
|
7
3
|
require 'active_record'
|
8
4
|
require 'minitest/autorun'
|
9
5
|
require 'minitest/reporters'
|
10
6
|
require 'minitest/stub_any_instance'
|
11
|
-
require 'shoulda/context'
|
12
7
|
require 'active_record_slave'
|
8
|
+
require 'awesome_print'
|
13
9
|
|
14
10
|
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
data/test/test_slave.sqlite3
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_slave
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Reid Morrison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -45,7 +45,7 @@ files:
|
|
45
45
|
- test/test.sqlite3
|
46
46
|
- test/test_helper.rb
|
47
47
|
- test/test_slave.sqlite3
|
48
|
-
homepage: https://github.com/
|
48
|
+
homepage: https://github.com/rocketjob/active_record_slave
|
49
49
|
licenses:
|
50
50
|
- Apache License V2.0
|
51
51
|
metadata: {}
|
@@ -65,10 +65,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
65
|
version: '0'
|
66
66
|
requirements: []
|
67
67
|
rubyforge_project:
|
68
|
-
rubygems_version: 2.
|
68
|
+
rubygems_version: 2.6.11
|
69
69
|
signing_key:
|
70
70
|
specification_version: 4
|
71
|
-
summary: ActiveRecord
|
71
|
+
summary: Redirect ActiveRecord (Rails) reads to slave databases while ensuring all
|
72
|
+
writes go to the master database.
|
72
73
|
test_files:
|
73
74
|
- test/active_record_slave_test.rb
|
74
75
|
- test/database.yml
|