ar-octopus 0.9.0 → 0.9.1

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +10 -2
  4. data/Appraisals +4 -0
  5. data/README.mkdn +1 -1
  6. data/gemfiles/rails51.gemfile +7 -0
  7. data/lib/octopus.rb +11 -6
  8. data/lib/octopus/collection_association.rb +9 -3
  9. data/lib/octopus/finder_methods.rb +1 -1
  10. data/lib/octopus/load_balancing/round_robin.rb +1 -0
  11. data/lib/octopus/log_subscriber.rb +6 -2
  12. data/lib/octopus/migration.rb +25 -9
  13. data/lib/octopus/model.rb +17 -25
  14. data/lib/octopus/proxy.rb +78 -279
  15. data/lib/octopus/proxy_config.rb +252 -0
  16. data/lib/octopus/relation_proxy.rb +7 -1
  17. data/lib/octopus/scope_proxy.rb +1 -1
  18. data/lib/octopus/shard_tracking.rb +2 -1
  19. data/lib/octopus/version.rb +1 -1
  20. data/spec/migrations/10_create_users_using_replication.rb +1 -1
  21. data/spec/migrations/11_add_field_in_all_slaves.rb +1 -1
  22. data/spec/migrations/12_create_users_using_block.rb +1 -1
  23. data/spec/migrations/13_create_users_using_block_and_using.rb +1 -1
  24. data/spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb +1 -1
  25. data/spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb +1 -1
  26. data/spec/migrations/1_create_users_on_master.rb +1 -1
  27. data/spec/migrations/2_create_users_on_canada.rb +1 -1
  28. data/spec/migrations/3_create_users_on_both_shards.rb +1 -1
  29. data/spec/migrations/4_create_users_on_shards_of_a_group.rb +1 -1
  30. data/spec/migrations/5_create_users_on_multiples_groups.rb +1 -1
  31. data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +1 -1
  32. data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +1 -1
  33. data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +1 -1
  34. data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +1 -1
  35. data/spec/octopus/association_shard_tracking_spec.rb +15 -15
  36. data/spec/octopus/load_balancing/round_robin_spec.rb +15 -0
  37. data/spec/octopus/log_subscriber_spec.rb +1 -1
  38. data/spec/octopus/model_spec.rb +34 -5
  39. data/spec/octopus/octopus_spec.rb +1 -1
  40. data/spec/octopus/proxy_spec.rb +16 -38
  41. data/spec/octopus/relation_proxy_spec.rb +4 -0
  42. data/spec/octopus/replication_spec.rb +5 -1
  43. data/spec/spec_helper.rb +2 -0
  44. data/spec/support/octopus_helper.rb +1 -2
  45. data/spec/tasks/octopus.rake_spec.rb +2 -4
  46. metadata +7 -6
  47. data/.ruby-version +0 -1
  48. data/init.rb +0 -1
  49. data/rails/init.rb +0 -1
@@ -0,0 +1,252 @@
1
+ module Octopus
2
+ class ProxyConfig
3
+ CURRENT_MODEL_KEY = 'octopus.current_model'.freeze
4
+ CURRENT_SHARD_KEY = 'octopus.current_shard'.freeze
5
+ CURRENT_GROUP_KEY = 'octopus.current_group'.freeze
6
+ CURRENT_SLAVE_GROUP_KEY = 'octopus.current_slave_group'.freeze
7
+ CURRENT_LOAD_BALANCE_OPTIONS_KEY = 'octopus.current_load_balance_options'.freeze
8
+ BLOCK_KEY = 'octopus.block'.freeze
9
+ FULLY_REPLICATED_KEY = 'octopus.fully_replicated'.freeze
10
+
11
+ attr_accessor :config, :sharded, :shards, :shards_slave_groups, :slave_groups,
12
+ :adapters, :replicated, :slaves_load_balancer, :slaves_list, :shards_slave_groups,
13
+ :slave_groups, :groups, :entire_sharded, :shards_config
14
+
15
+ def initialize(config)
16
+ initialize_shards(config)
17
+ initialize_replication(config) if !config.nil? && config['replicated']
18
+ end
19
+
20
+ def current_model
21
+ Thread.current[CURRENT_MODEL_KEY]
22
+ end
23
+
24
+ def current_model=(model)
25
+ Thread.current[CURRENT_MODEL_KEY] = model.is_a?(ActiveRecord::Base) ? model.class : model
26
+ end
27
+
28
+ def current_shard
29
+ Thread.current[CURRENT_SHARD_KEY] ||= Octopus.master_shard
30
+ end
31
+
32
+ def current_shard=(shard_symbol)
33
+ if shard_symbol.is_a?(Array)
34
+ self.current_slave_group = nil
35
+ shard_symbol.each { |symbol| fail "Nonexistent Shard Name: #{symbol}" if shards[symbol].nil? }
36
+ elsif shard_symbol.is_a?(Hash)
37
+ hash = shard_symbol
38
+ shard_symbol = hash[:shard]
39
+ slave_group_symbol = hash[:slave_group]
40
+ load_balance_options = hash[:load_balance_options]
41
+
42
+ if shard_symbol.nil? && slave_group_symbol.nil?
43
+ fail 'Neither shard or slave group must be specified'
44
+ end
45
+
46
+ if shard_symbol.present?
47
+ fail "Nonexistent Shard Name: #{shard_symbol}" if shards[shard_symbol].nil?
48
+ end
49
+
50
+ if slave_group_symbol.present?
51
+ if (shards_slave_groups.try(:[], shard_symbol).present? && shards_slave_groups[shard_symbol][slave_group_symbol].nil?) ||
52
+ (shards_slave_groups.try(:[], shard_symbol).nil? && @slave_groups[slave_group_symbol].nil?)
53
+ fail "Nonexistent Slave Group Name: #{slave_group_symbol} in shards config: #{shards_config.inspect}"
54
+ end
55
+ end
56
+ self.current_slave_group = slave_group_symbol
57
+ self.current_load_balance_options = load_balance_options
58
+ else
59
+ fail "Nonexistent Shard Name: #{shard_symbol}" if shards[shard_symbol].nil?
60
+ end
61
+
62
+ Thread.current[CURRENT_SHARD_KEY] = shard_symbol
63
+ end
64
+
65
+ def current_group
66
+ Thread.current[CURRENT_GROUP_KEY]
67
+ end
68
+
69
+ def current_group=(group_symbol)
70
+ # TODO: Error message should include all groups if given more than one bad name.
71
+ [group_symbol].flatten.compact.each do |group|
72
+ fail "Nonexistent Group Name: #{group}" unless has_group?(group)
73
+ end
74
+
75
+ Thread.current[CURRENT_GROUP_KEY] = group_symbol
76
+ end
77
+
78
+ def current_slave_group
79
+ Thread.current[CURRENT_SLAVE_GROUP_KEY]
80
+ end
81
+
82
+ def current_slave_group=(slave_group_symbol)
83
+ Thread.current[CURRENT_SLAVE_GROUP_KEY] = slave_group_symbol
84
+ Thread.current[CURRENT_LOAD_BALANCE_OPTIONS_KEY] = nil if slave_group_symbol.nil?
85
+ end
86
+
87
+ def current_load_balance_options
88
+ Thread.current[CURRENT_LOAD_BALANCE_OPTIONS_KEY]
89
+ end
90
+
91
+ def current_load_balance_options=(options)
92
+ Thread.current[CURRENT_LOAD_BALANCE_OPTIONS_KEY] = options
93
+ end
94
+
95
+ def block
96
+ Thread.current[BLOCK_KEY]
97
+ end
98
+
99
+ def block=(block)
100
+ Thread.current[BLOCK_KEY] = block
101
+ end
102
+
103
+ def fully_replicated?
104
+ @fully_replicated || Thread.current[FULLY_REPLICATED_KEY]
105
+ end
106
+
107
+ # Public: Whether or not a group exists with the given name converted to a
108
+ # string.
109
+ #
110
+ # Returns a boolean.
111
+ def has_group?(group)
112
+ @groups.key?(group.to_s)
113
+ end
114
+
115
+ # Public: Retrieves names of all loaded shards.
116
+ #
117
+ # Returns an array of shard names as symbols
118
+ def shard_names
119
+ shards.keys
120
+ end
121
+
122
+ def shard_name
123
+ current_shard.is_a?(Array) ? current_shard.first : current_shard
124
+ end
125
+
126
+ # Public: Retrieves the defined shards for a given group.
127
+ #
128
+ # Returns an array of shard names as symbols or nil if the group is not
129
+ # defined.
130
+ def shards_for_group(group)
131
+ @groups.fetch(group.to_s, nil)
132
+ end
133
+
134
+ def initialize_shards(config)
135
+ self.config = config
136
+
137
+ self.shards = HashWithIndifferentAccess.new
138
+ self.shards_slave_groups = HashWithIndifferentAccess.new
139
+ self.slave_groups = HashWithIndifferentAccess.new
140
+ self.groups = {}
141
+ self.config = ActiveRecord::Base.connection_pool_without_octopus.spec.config
142
+
143
+ unless config.nil?
144
+ self.entire_sharded = config['entire_sharded']
145
+ self.shards_config = config[Octopus.rails_env]
146
+ end
147
+
148
+ self.shards_config ||= []
149
+
150
+ shards_config.each do |key, value|
151
+ if value.is_a?(String)
152
+ value = resolve_string_connection(value).merge(:octopus_shard => key)
153
+ initialize_adapter(value['adapter'])
154
+ shards[key.to_sym] = connection_pool_for(value, "#{value['adapter']}_connection")
155
+ elsif value.is_a?(Hash) && value.key?('adapter')
156
+ value.merge!(:octopus_shard => key)
157
+ initialize_adapter(value['adapter'])
158
+ shards[key.to_sym] = connection_pool_for(value, "#{value['adapter']}_connection")
159
+
160
+ slave_group_configs = value.select do |_k, v|
161
+ structurally_slave_group? v
162
+ end
163
+
164
+ if slave_group_configs.present?
165
+ slave_groups = HashWithIndifferentAccess.new
166
+ slave_group_configs.each do |slave_group_name, slave_configs|
167
+ slaves = HashWithIndifferentAccess.new
168
+ slave_configs.each do |slave_name, slave_config|
169
+ shards[slave_name.to_sym] = connection_pool_for(slave_config, "#{value['adapter']}_connection")
170
+ slaves[slave_name.to_sym] = slave_name.to_sym
171
+ end
172
+ slave_groups[slave_group_name.to_sym] = Octopus::SlaveGroup.new(slaves)
173
+ end
174
+ @shards_slave_groups[key.to_sym] = slave_groups
175
+ @sharded = true
176
+ end
177
+ elsif value.is_a?(Hash)
178
+ @groups[key.to_s] = []
179
+
180
+ value.each do |k, v|
181
+ fail 'You have duplicated shard names!' if shards.key?(k.to_sym)
182
+
183
+ initialize_adapter(v['adapter'])
184
+ config_with_octopus_shard = v.merge(:octopus_shard => k)
185
+
186
+ shards[k.to_sym] = connection_pool_for(config_with_octopus_shard, "#{v['adapter']}_connection")
187
+ @groups[key.to_s] << k.to_sym
188
+ end
189
+
190
+ if structurally_slave_group? value
191
+ slaves = Hash[@groups[key.to_s].map { |v| [v, v] }]
192
+ @slave_groups[key.to_sym] = Octopus::SlaveGroup.new(slaves)
193
+ end
194
+ end
195
+ end
196
+
197
+ shards[:master] ||= ActiveRecord::Base.connection_pool_without_octopus if Octopus.master_shard == :master
198
+ end
199
+
200
+ def initialize_replication(config)
201
+ @replicated = true
202
+ if config.key?('fully_replicated')
203
+ @fully_replicated = config['fully_replicated']
204
+ else
205
+ @fully_replicated = true
206
+ end
207
+
208
+ @slaves_list = shards.keys.map(&:to_s).sort
209
+ @slaves_list.delete('master')
210
+ @slaves_load_balancer = Octopus.load_balancer.new(@slaves_list)
211
+ end
212
+
213
+ private
214
+
215
+ def connection_pool_for(adapter, config)
216
+ if Octopus.rails4?
217
+ arg = ActiveRecord::ConnectionAdapters::ConnectionSpecification.new(adapter.dup, config)
218
+ else
219
+ name = adapter["octopus_shard"]
220
+ arg = ActiveRecord::ConnectionAdapters::ConnectionSpecification.new(name, adapter.dup, config)
221
+ end
222
+
223
+ ActiveRecord::ConnectionAdapters::ConnectionPool.new(arg)
224
+ end
225
+
226
+ def resolve_string_connection(spec)
227
+ if Octopus.rails41? || Octopus.rails50? || Octopus.rails51?
228
+ resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new({})
229
+ HashWithIndifferentAccess.new(resolver.spec(spec).config)
230
+ else
231
+ resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(spec, {})
232
+ HashWithIndifferentAccess.new(resolver.spec.config)
233
+ end
234
+ end
235
+
236
+ def structurally_slave?(config)
237
+ config.is_a?(Hash) && config.key?('adapter')
238
+ end
239
+
240
+ def structurally_slave_group?(config)
241
+ config.is_a?(Hash) && config.values.any? { |v| structurally_slave? v }
242
+ end
243
+
244
+ def initialize_adapter(adapter)
245
+ begin
246
+ require "active_record/connection_adapters/#{adapter}_adapter"
247
+ rescue LoadError
248
+ raise "Please install the #{adapter} adapter: `gem install activerecord-#{adapter}-adapter` (#{$ERROR_INFO})"
249
+ end
250
+ end
251
+ end
252
+ end
@@ -24,7 +24,13 @@ module Octopus
24
24
  if block
25
25
  @ar_relation.public_send(method, *args, &block)
26
26
  else
27
- run_on_shard { @ar_relation.public_send(method, *args) }
27
+ run_on_shard do
28
+ if method == :load_records
29
+ @ar_relation.send(method, *args)
30
+ else
31
+ @ar_relation.public_send(method, *args)
32
+ end
33
+ end
28
34
  end
29
35
  end
30
36
 
@@ -21,7 +21,7 @@ module Octopus
21
21
  end
22
22
 
23
23
  def using(shard)
24
- fail "Nonexistent Shard Name: #{shard}" if @klass.connection.instance_variable_get(:@shards)[shard].nil?
24
+ fail "Nonexistent Shard Name: #{shard}" if @klass.connection.shards[shard].nil?
25
25
  @current_shard = shard
26
26
  self
27
27
  end
@@ -20,7 +20,8 @@ module Octopus
20
20
  define_method with do |*args, &block|
21
21
  run_on_shard { send(without, *args, &block) }
22
22
  end
23
- alias_method_chain name.to_sym, :octopus
23
+ alias_method without.to_sym, name.to_sym
24
+ alias_method name.to_sym, with.to_sym
24
25
  end
25
26
  end
26
27
 
@@ -1,3 +1,3 @@
1
1
  module Octopus
2
- VERSION = '0.9.0'
2
+ VERSION = '0.9.1'
3
3
  end
@@ -1,4 +1,4 @@
1
- class CreateUsersUsingReplication < ActiveRecord::Migration
1
+ class CreateUsersUsingReplication < BaseOctopusMigrationClass
2
2
  def self.up
3
3
  Cat.create!(:name => 'Replication')
4
4
  end
@@ -1,4 +1,4 @@
1
- class AddFieldInAllSlaves < ActiveRecord::Migration
1
+ class AddFieldInAllSlaves < BaseOctopusMigrationClass
2
2
  using(:slave1, :slave2, :slave3, :slave4)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class CreateUsersUsingBlock < ActiveRecord::Migration
1
+ class CreateUsersUsingBlock < BaseOctopusMigrationClass
2
2
  def self.up
3
3
  Octopus.using(:brazil) do
4
4
  User.create!(:name => 'UsingBlock1')
@@ -1,4 +1,4 @@
1
- class CreateUsersUsingBlockAndUsing < ActiveRecord::Migration
1
+ class CreateUsersUsingBlockAndUsing < BaseOctopusMigrationClass
2
2
  using(:brazil)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class CreateUsersOnShardsOfAGroupWithVersions < ActiveRecord::Migration
1
+ class CreateUsersOnShardsOfAGroupWithVersions < BaseOctopusMigrationClass
2
2
  using_group(:country_shards)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class CreateUserOnShardsOfDefaultGroupWithVersions < ActiveRecord::Migration
1
+ class CreateUserOnShardsOfDefaultGroupWithVersions < BaseOctopusMigrationClass
2
2
  def self.up
3
3
  User.create!(:name => 'Default Group')
4
4
  end
@@ -1,4 +1,4 @@
1
- class CreateUsersOnMaster < ActiveRecord::Migration
1
+ class CreateUsersOnMaster < BaseOctopusMigrationClass
2
2
  def self.up
3
3
  User.create!(:name => 'Master')
4
4
  end
@@ -1,4 +1,4 @@
1
- class CreateUsersOnCanada < ActiveRecord::Migration
1
+ class CreateUsersOnCanada < BaseOctopusMigrationClass
2
2
  using(:canada)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class CreateUsersOnBothShards < ActiveRecord::Migration
1
+ class CreateUsersOnBothShards < BaseOctopusMigrationClass
2
2
  using(:brazil, :canada)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class CreateUsersOnShardsOfAGroup < ActiveRecord::Migration
1
+ class CreateUsersOnShardsOfAGroup < BaseOctopusMigrationClass
2
2
  using_group(:country_shards)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class CreateUsersOnMultiplesGroups < ActiveRecord::Migration
1
+ class CreateUsersOnMultiplesGroups < BaseOctopusMigrationClass
2
2
  using_group('country_shards', 'history_shards')
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class RaiseExceptionWithInvalidShardName < ActiveRecord::Migration
1
+ class RaiseExceptionWithInvalidShardName < BaseOctopusMigrationClass
2
2
  using(:amazing_shard)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class RaiseExceptionWithInvalidMultipleShardNames < ActiveRecord::Migration
1
+ class RaiseExceptionWithInvalidMultipleShardNames < BaseOctopusMigrationClass
2
2
  using(:brazil, :invalid_shard)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class RaiseExceptionWithInvalidGroupName < ActiveRecord::Migration
1
+ class RaiseExceptionWithInvalidGroupName < BaseOctopusMigrationClass
2
2
  using_group(:invalid_group)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class RaiseExceptionWithMultipleInvalidGroupNames < ActiveRecord::Migration
1
+ class RaiseExceptionWithMultipleInvalidGroupNames < BaseOctopusMigrationClass
2
2
  using_group(:country_shards, :invalid_group)
3
3
 
4
4
  def self.up
@@ -96,7 +96,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
96
96
  expect(@permission_brazil.roles).to eq([new_brazil_role])
97
97
  end
98
98
 
99
- it 'should works for build method' do
99
+ it 'should work for build method' do
100
100
  new_brazil_role = Role.using(:brazil).create!(:name => 'Brazil Role')
101
101
  c = new_brazil_role.permissions.create(:name => 'new Permission')
102
102
  c.save
@@ -105,7 +105,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
105
105
  expect(new_brazil_role.permissions).to eq([c])
106
106
  end
107
107
 
108
- describe 'it should works when using' do
108
+ describe 'it should work when using' do
109
109
  before(:each) do
110
110
  @permission_brazil_2 = Permission.using(:brazil).create!(:name => 'Brazil Item 2')
111
111
  @role = Role.using(:brazil).create!(:name => 'testes')
@@ -198,9 +198,9 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
198
198
 
199
199
  it 'exists?' do
200
200
  role = @permission_brazil_2.roles.create(:name => 'Builded Role')
201
- expect(@permission_brazil_2.roles.exists?(role)).to be true
201
+ expect(@permission_brazil_2.roles.exists?(role.id)).to be true
202
202
  @permission_brazil_2.roles.destroy_all
203
- expect(@permission_brazil_2.roles.exists?(role)).to be false
203
+ expect(@permission_brazil_2.roles.exists?(role.id)).to be false
204
204
  end
205
205
 
206
206
  it 'clear' do
@@ -250,7 +250,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
250
250
  expect(@project.programmers).to eq([new_brazil_programmer])
251
251
  end
252
252
 
253
- it 'should works for create method' do
253
+ it 'should work for create method' do
254
254
  new_brazil_programmer = Programmer.using(:brazil).create!(:name => 'Joao')
255
255
  c = new_brazil_programmer.projects.create(:name => 'new Project')
256
256
  c.save
@@ -259,7 +259,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
259
259
  expect(new_brazil_programmer.projects).to eq([c])
260
260
  end
261
261
 
262
- describe 'it should works when using' do
262
+ describe 'it should work when using' do
263
263
  before(:each) do
264
264
  @new_brazil_programmer = Programmer.using(:brazil).create!(:name => 'Jose')
265
265
  @project = Project.using(:brazil).create!(:name => 'VB Application :-(')
@@ -352,9 +352,9 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
352
352
 
353
353
  it 'exists?' do
354
354
  role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
355
- expect(@new_brazil_programmer.projects.exists?(role)).to be true
355
+ expect(@new_brazil_programmer.projects.exists?(role.id)).to be true
356
356
  @new_brazil_programmer.projects.destroy_all
357
- expect(@new_brazil_programmer.projects.exists?(role)).to be false
357
+ expect(@new_brazil_programmer.projects.exists?(role.id)).to be false
358
358
  end
359
359
 
360
360
  it 'clear' do
@@ -414,7 +414,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
414
414
  expect(@item_brazil.client).to eq(new_brazil_client)
415
415
  end
416
416
 
417
- it 'should works for build method' do
417
+ it 'should work for build method' do
418
418
  item2 = Item.using(:brazil).create!(:name => 'Brazil Item')
419
419
  c = item2.create_client(:name => 'new Client')
420
420
  c.save
@@ -442,7 +442,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
442
442
  end
443
443
  end
444
444
 
445
- describe 'it should works when using' do
445
+ describe 'it should work when using' do
446
446
  before(:each) do
447
447
  @item_brazil_2 = Item.using(:brazil).create!(:name => 'Brazil Item 2')
448
448
  expect(@brazil_client.items.to_set).to eq([@item_brazil].to_set)
@@ -540,9 +540,9 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
540
540
  end
541
541
 
542
542
  it 'exists?' do
543
- expect(@brazil_client.items.exists?(@item_brazil)).to be true
543
+ expect(@brazil_client.items.exists?(@item_brazil.id)).to be true
544
544
  @brazil_client.items.destroy_all
545
- expect(@brazil_client.items.exists?(@item_brazil)).to be false
545
+ expect(@brazil_client.items.exists?(@item_brazil.id)).to be false
546
546
  end
547
547
 
548
548
  it 'uniq' do
@@ -586,7 +586,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
586
586
  expect(@comment_brazil.commentable).to eq(new_brazil_client)
587
587
  end
588
588
 
589
- describe 'it should works when using' do
589
+ describe 'it should work when using' do
590
590
  before(:each) do
591
591
  @comment_brazil_2 = Comment.using(:brazil).create!(:name => 'Brazil Comment 2')
592
592
  expect(@brazil_client.comments.to_set).to eq([@comment_brazil].to_set)
@@ -690,9 +690,9 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
690
690
  end
691
691
 
692
692
  it 'exists?' do
693
- expect(@brazil_client.comments.exists?(@comment_brazil)).to be true
693
+ expect(@brazil_client.comments.exists?(@comment_brazil.id)).to be true
694
694
  @brazil_client.comments.destroy_all
695
- expect(@brazil_client.comments.exists?(@comment_brazil)).to be false
695
+ expect(@brazil_client.comments.exists?(@comment_brazil.id)).to be false
696
696
  end
697
697
 
698
698
  it 'uniq' do