ar-octopus 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  require "set"
2
2
 
3
3
  class Octopus::Proxy
4
- attr_accessor :shards, :current_shard, :block, :groups, :current_group, :replicated, :slaves_list, :replicated_models, :using_enabled
4
+ attr_accessor :shards, :block, :groups, :current_group, :replicated, :slaves_list, :replicated_models, :using_enabled, :last_current_shard
5
5
 
6
6
  delegate :increment_open_transactions, :decrement_open_transactions, :to => :select_connection
7
7
 
@@ -9,12 +9,18 @@ class Octopus::Proxy
9
9
  @shards = {}
10
10
  @groups = {}
11
11
  @replicated_models = Set.new
12
- @block = false
13
- @replicated = config[Octopus.env()]["replicated"] || false
12
+ @replicated = config[Octopus.env()]["replicated"]
14
13
  @shards[:master] = ActiveRecord::Base.connection_pool()
15
- @current_shard = :master
16
- @using_enabled = false
17
-
14
+ Thread.current[:current_shard] = :master
15
+
16
+ initialize_shards(config)
17
+
18
+ if @replicated
19
+ initialize_replication()
20
+ end
21
+ end
22
+
23
+ def initialize_shards(config)
18
24
  config[Octopus.env()]["shards"].each do |key, value|
19
25
  if value.has_key?("adapter")
20
26
  initialize_adapter(value['adapter'])
@@ -30,14 +36,18 @@ class Octopus::Proxy
30
36
  end
31
37
  end
32
38
  end
33
-
34
- if @replicated
35
- @slaves_list = @shards.keys
36
- @slaves_list.delete(:master)
37
- @slaves_list = @slaves_list.map {|sym| sym.to_s}.sort
38
- end
39
39
  end
40
-
40
+
41
+ def initialize_replication()
42
+ @slaves_list = @shards.keys
43
+ @slaves_list.delete(:master)
44
+ @slaves_list = @slaves_list.map {|sym| sym.to_s}.sort
45
+ end
46
+
47
+ def current_shard
48
+ Thread.current[:current_shard]
49
+ end
50
+
41
51
  def current_shard=(shard_symbol)
42
52
  if shard_symbol.is_a?(Array)
43
53
  shard_symbol.each {|symbol| raise "Nonexistent Shard Name: #{symbol}" if @shards[symbol].nil? }
@@ -45,7 +55,7 @@ class Octopus::Proxy
45
55
  raise "Nonexistent Shard Name: #{shard_symbol}" if @shards[shard_symbol].nil?
46
56
  end
47
57
 
48
- @current_shard = shard_symbol
58
+ Thread.current[:current_shard] = shard_symbol
49
59
  end
50
60
 
51
61
  def current_group=(group_symbol)
@@ -57,7 +67,7 @@ class Octopus::Proxy
57
67
 
58
68
  @current_group = group_symbol
59
69
  end
60
-
70
+
61
71
  def select_connection()
62
72
  @shards[shard_name].connection()
63
73
  end
@@ -83,13 +93,11 @@ class Octopus::Proxy
83
93
  def transaction(options = {}, &block)
84
94
  if should_send_queries_to_multiple_shards?
85
95
  self.send_transaction_to_multiple_shards(current_shard, options, &block)
86
- self.current_shard = :master
87
96
  elsif should_send_queries_to_multiple_groups?
88
97
  self.send_transaction_to_multiple_groups(options, &block)
89
- self.current_group = nil
90
98
  elsif should_send_queries_to_a_group_of_shards?
91
99
  self.send_transaction_to_multiple_shards(@groups[current_group], options, &block)
92
- self.current_group = nil
100
+ self.current_group = nil
93
101
  else
94
102
  select_connection.transaction(options, &block)
95
103
  end
@@ -98,6 +106,7 @@ class Octopus::Proxy
98
106
  def method_missing(method, *args, &block)
99
107
  if should_clean_connection?(method)
100
108
  conn = select_connection()
109
+ self.last_current_shard = self.current_shard
101
110
  self.current_shard = :master
102
111
  @using_enabled = nil
103
112
  conn.send(method, *args, &block)
@@ -113,7 +122,19 @@ class Octopus::Proxy
113
122
  select_connection().send(method, *args, &block)
114
123
  end
115
124
  end
116
-
125
+
126
+ def run_query_on_shard(shard, &block)
127
+ older_shard = self.current_shard
128
+ self.block = true
129
+ self.current_shard = shard
130
+ begin
131
+ yield
132
+ ensure
133
+ self.block = false
134
+ self.current_shard = older_shard
135
+ end
136
+ end
137
+
117
138
  protected
118
139
  def connection_pool_for(adapter, config)
119
140
  ActiveRecord::ConnectionAdapters::ConnectionPool.new(ActiveRecord::Base::ConnectionSpecification.new(adapter, config))
@@ -134,7 +155,7 @@ class Octopus::Proxy
134
155
  end
135
156
 
136
157
  def should_clean_connection?(method)
137
- method.to_s =~ /begin_db_transaction|insert|select/ && !should_send_queries_to_multiple_shards? && !self.current_group && !replicated
158
+ method.to_s =~ /insert|select/ && !should_send_queries_to_multiple_shards? && !self.current_group && !replicated
138
159
  end
139
160
 
140
161
  def should_send_queries_to_multiple_shards?
@@ -150,7 +171,7 @@ class Octopus::Proxy
150
171
  end
151
172
 
152
173
  def should_send_queries_to_replicated_databases?(method)
153
- @replicated && method.to_s == "select_all"
174
+ @replicated && method.to_s =~ /select/
154
175
  end
155
176
 
156
177
  def send_queries_to_multiple_groups(method, *args, &block)
@@ -20,4 +20,35 @@ end
20
20
  #This items belongs to a client
21
21
  class Item < ActiveRecord::Base
22
22
  belongs_to :client
23
+ end
24
+
25
+ class Keyboard < ActiveRecord::Base
26
+ belongs_to :computer
27
+ end
28
+
29
+ class Computer < ActiveRecord::Base
30
+ has_one :keyboard
31
+ end
32
+
33
+ class Role < ActiveRecord::Base
34
+ has_and_belongs_to_many :permissions
35
+ end
36
+
37
+ class Permission < ActiveRecord::Base
38
+ has_and_belongs_to_many :roles
39
+ end
40
+
41
+ class Assignment < ActiveRecord::Base
42
+ belongs_to :programmer
43
+ belongs_to :project
44
+ end
45
+
46
+ class Programmer < ActiveRecord::Base
47
+ has_many :assignments
48
+ has_many :projects, :through => :assignments
49
+ end
50
+
51
+ class Project < ActiveRecord::Base
52
+ has_many :assignments
53
+ has_many :programmers, :through => :assignments
23
54
  end
@@ -0,0 +1,518 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Octopus::Association do
4
+ describe "when you have a 1 x 1 relationship" do
5
+ before(:each) do
6
+ @computer_brazil = Computer.using(:brazil).create!(:name => "Computer Brazil")
7
+ @computer_master = Computer.create!(:name => "Computer Brazil")
8
+ @keyboard_brazil = Keyboard.using(:brazil).create!(:name => "Keyboard Brazil", :computer => @computer_brazil)
9
+ @keyboard_master = Keyboard.create!(:name => "Keyboard Master", :computer => @computer_master)
10
+ end
11
+
12
+ it "should find the models" do
13
+ @keyboard_master.computer.should == @computer_master
14
+ @keyboard_brazil.computer.should == @computer_brazil
15
+ end
16
+
17
+ it "should read correctly the relationed model" do
18
+ new_computer_brazil = Computer.using(:brazil).create!(:name => "New Computer Brazil")
19
+ new_computer_master = Computer.create!(:name => "New Computer Brazil")
20
+ @keyboard_brazil.computer = new_computer_brazil
21
+ @keyboard_brazil.save()
22
+ @keyboard_brazil.reload
23
+ @keyboard_brazil.computer_id.should == new_computer_brazil.id
24
+ @keyboard_brazil.computer.should == new_computer_brazil
25
+ new_computer_brazil.save()
26
+ new_computer_brazil.reload
27
+ new_computer_brazil.keyboard.should == @keyboard_brazil
28
+ end
29
+
30
+ it "should work when using #build_computer or #build_keyboard" do
31
+ c = Computer.using(:brazil).create!(:name => "Computer Brazil")
32
+ k = c.build_keyboard(:name => "Building keyboard")
33
+ c.save()
34
+ k.save()
35
+ c.keyboard.should == k
36
+ k.computer_id.should == c.id
37
+ k.computer.should == c
38
+ end
39
+
40
+ it "should work when using #create_computer or #create_keyboard" do
41
+ c = Computer.using(:brazil).create!(:name => "Computer Brazil")
42
+ k = c.create_keyboard(:name => "Building keyboard")
43
+ c.save()
44
+ k.save()
45
+ c.keyboard.should == k
46
+ k.computer_id.should == c.id
47
+ k.computer.should == c
48
+ end
49
+
50
+ it "should works when using create!" do
51
+ c = Computer.using(:brazil).create!(:name => "Computer Brazil")
52
+ k = c.keyboard.create!(:name => "New Keyboard")
53
+ c.save()
54
+ k.save()
55
+ c.reload()
56
+ k.reload()
57
+ c.keyboard.should == k
58
+ k.computer_id.should == c.id
59
+ k.computer.should == c
60
+ end
61
+ end
62
+
63
+ describe "when you have a N x N reliationship" do
64
+ before(:each) do
65
+ @brazil_role = Role.using(:brazil).create!(:name => "Brazil Role")
66
+ @master_role = Role.create!(:name => "Master Role")
67
+ @permission_brazil = Permission.using(:brazil).create!(:name => "Brazil Permission")
68
+ @permission_master = Permission.using(:master).create!(:name => "Master Permission")
69
+ @brazil_role.permissions << @permission_brazil
70
+ @brazil_role.save()
71
+ Client.using(:master).create!(:name => "teste")
72
+ end
73
+
74
+ it "should find all models in the specified shard" do
75
+ @brazil_role.permission_ids().should == [@permission_brazil.id]
76
+ @brazil_role.permissions().should == [@permission_brazil]
77
+ end
78
+
79
+ it "should finds the client that the item belongs" do
80
+ @permission_brazil.role_ids.should == [@brazil_role.id]
81
+ @permission_brazil.roles.should == [@brazil_role]
82
+ end
83
+
84
+ it "should update the attribute for the item" do
85
+ new_brazil_role = Role.using(:brazil).create!(:name => "new Role")
86
+ @permission_brazil.roles = [new_brazil_role]
87
+ @permission_brazil.roles.should == [new_brazil_role]
88
+ @permission_brazil.save()
89
+ @permission_brazil.reload
90
+ @permission_brazil.role_ids.should == [new_brazil_role.id]
91
+ @permission_brazil.roles().should == [new_brazil_role]
92
+ end
93
+
94
+ it "should works for build method" do
95
+ new_brazil_role = Role.using(:brazil).create!(:name => "Brazil Role")
96
+ c = new_brazil_role.permissions.create(:name => "new Permission")
97
+ c.save()
98
+ new_brazil_role.save()
99
+ c.roles().should == [new_brazil_role]
100
+ new_brazil_role.permissions.should == [c]
101
+ end
102
+
103
+ describe "it should works when using" do
104
+ before(:each) do
105
+ @permission_brazil_2 = Permission.using(:brazil).create!(:name => "Brazil Item 2")
106
+ @role = Role.using(:brazil).create!(:name => "testes")
107
+ end
108
+
109
+ it "update_attributes" do
110
+ @permission_brazil_2.update_attributes(:role_ids => [@role.id])
111
+ @permission_brazil_2.roles.to_set.should == [@role].to_set
112
+ end
113
+
114
+ it "update_attribute" do
115
+ @permission_brazil_2.update_attribute(:role_ids, [@role.id])
116
+ @permission_brazil_2.roles.to_set.should == [@role].to_set
117
+ end
118
+
119
+ it "<<" do
120
+ @permission_brazil_2.roles << @role
121
+ @role.save()
122
+ @permission_brazil_2.save()
123
+ @permission_brazil_2.reload
124
+ @permission_brazil_2.roles.to_set.should == [@role].to_set
125
+ end
126
+
127
+ it "build" do
128
+ role = @permission_brazil_2.roles.build(:name => "Builded Role")
129
+ @permission_brazil_2.save()
130
+ @permission_brazil_2.roles.to_set.should == [role].to_set
131
+ end
132
+
133
+ it "create" do
134
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
135
+ @permission_brazil_2.roles.to_set.should == [role].to_set
136
+ end
137
+
138
+ it "create" do
139
+ role = @permission_brazil_2.roles.create!(:name => "Builded Role")
140
+ @permission_brazil_2.roles.to_set.should == [role].to_set
141
+ end
142
+
143
+ it "count" do
144
+ @permission_brazil_2.roles.count.should == 0
145
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
146
+ @permission_brazil_2.roles.count.should == 1
147
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
148
+ @permission_brazil_2.roles.count.should == 2
149
+ end
150
+
151
+ it "size" do
152
+ @permission_brazil_2.roles.size.should == 0
153
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
154
+ @permission_brazil_2.roles.size.should == 1
155
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
156
+ @permission_brazil_2.roles.size.should == 2
157
+ end
158
+
159
+ it "length" do
160
+ @permission_brazil_2.roles.length.should == 0
161
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
162
+ @permission_brazil_2.roles.length.should == 1
163
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
164
+ @permission_brazil_2.roles.length.should == 2
165
+ end
166
+
167
+
168
+ it "empty?" do
169
+ @permission_brazil_2.roles.empty?.should be_true
170
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
171
+ @permission_brazil_2.roles.empty?.should be_false
172
+ end
173
+
174
+ it "delete_all" do
175
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
176
+ @permission_brazil_2.roles.empty?.should be_false
177
+ @permission_brazil_2.roles.delete_all
178
+ @permission_brazil_2.roles.empty?.should be_true
179
+ end
180
+
181
+ it "destroy_all" do
182
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
183
+ @permission_brazil_2.roles.empty?.should be_false
184
+ @permission_brazil_2.roles.destroy_all
185
+ @permission_brazil_2.roles.empty?.should be_true
186
+ end
187
+
188
+ it "find" do
189
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
190
+ @permission_brazil_2.roles.find(:first).should == role
191
+ @permission_brazil_2.roles.destroy_all
192
+ @permission_brazil_2.roles.find(:first).should be_nil
193
+ end
194
+
195
+ it "exists?" do
196
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
197
+ @permission_brazil_2.roles.exists?(role).should be_true
198
+ @permission_brazil_2.roles.destroy_all
199
+ @permission_brazil_2.roles.exists?(role).should be_false
200
+ end
201
+
202
+ it "clear" do
203
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
204
+ @permission_brazil_2.roles.empty?.should be_false
205
+ @permission_brazil_2.roles.clear
206
+ @permission_brazil_2.roles.empty?.should be_true
207
+ end
208
+
209
+ it "delete" do
210
+ role = @permission_brazil_2.roles.create(:name => "Builded Role")
211
+ @permission_brazil_2.roles.empty?.should be_false
212
+ @permission_brazil_2.roles.delete(role)
213
+ @permission_brazil_2.reload
214
+ @role.reload
215
+ @role.permissions.should == []
216
+ @permission_brazil_2.roles.should == []
217
+ end
218
+ end
219
+ end
220
+
221
+ describe "when you have has_many :through" do
222
+ before(:each) do
223
+ @programmer = Programmer.using(:brazil).create!(:name => "Thiago")
224
+ @project = Project.using(:brazil).create!(:name => "RubySoc")
225
+ @project2 = Project.using(:brazil).create!(:name => "Cobol Application")
226
+ @programmer.projects << @project
227
+ @programmer.save()
228
+ Project.using(:master).create!(:name => "Project Master")
229
+ end
230
+
231
+ it "should find all models in the specified shard" do
232
+ @programmer.project_ids().should == [ @project.id]
233
+ @programmer.projects().should == [@project]
234
+ end
235
+
236
+
237
+ it "should update the attribute for the item" do
238
+ new_brazil_programmer = Programmer.using(:brazil).create!(:name => "Joao")
239
+ @project.programmers = [new_brazil_programmer]
240
+ @project.programmers.should == [new_brazil_programmer]
241
+ @project.save()
242
+ @project.reload
243
+ @project.programmer_ids.should == [new_brazil_programmer.id]
244
+ @project.programmers().should == [new_brazil_programmer]
245
+ end
246
+
247
+ it "should works for create method" do
248
+ new_brazil_programmer = Programmer.using(:brazil).create!(:name => "Joao")
249
+ c = new_brazil_programmer.projects.create(:name => "new Project")
250
+ c.save()
251
+ new_brazil_programmer.save()
252
+ c.programmers().should == [new_brazil_programmer]
253
+ new_brazil_programmer.projects.should == [c]
254
+ end
255
+
256
+ describe "it should works when using" do
257
+ before(:each) do
258
+ @new_brazil_programmer = Programmer.using(:brazil).create!(:name => "Jose")
259
+ @project = Project.using(:brazil).create!(:name => "VB Application :-(")
260
+ end
261
+
262
+ it "update_attributes" do
263
+ @new_brazil_programmer.update_attributes(:project_ids => [@project.id])
264
+ @new_brazil_programmer.projects.to_set.should == [@project].to_set
265
+ end
266
+
267
+ it "update_attribute" do
268
+ @new_brazil_programmer.update_attribute(:project_ids, [@project.id])
269
+ @new_brazil_programmer.projects.to_set.should == [@project].to_set
270
+ end
271
+
272
+ it "<<" do
273
+ @new_brazil_programmer.projects << @project
274
+ @project.save()
275
+ @new_brazil_programmer.save()
276
+ @new_brazil_programmer.reload
277
+ @new_brazil_programmer.projects.to_set.should == [@project].to_set
278
+ end
279
+
280
+ it "build" do
281
+ role = @new_brazil_programmer.projects.build(:name => "New VB App :-/")
282
+ @new_brazil_programmer.save()
283
+ @new_brazil_programmer.projects.to_set.should == [role].to_set
284
+ end
285
+
286
+ it "create" do
287
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
288
+ @new_brazil_programmer.projects.to_set.should == [role].to_set
289
+ end
290
+
291
+ it "create" do
292
+ role = @new_brazil_programmer.projects.create!(:name => "New VB App :-/")
293
+ @new_brazil_programmer.projects.to_set.should == [role].to_set
294
+ end
295
+
296
+ it "count" do
297
+ @new_brazil_programmer.projects.count.should == 0
298
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
299
+ @new_brazil_programmer.projects.count.should == 1
300
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
301
+ @new_brazil_programmer.projects.count.should == 2
302
+ end
303
+
304
+ it "size" do
305
+ @new_brazil_programmer.projects.size.should == 0
306
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
307
+ @new_brazil_programmer.projects.size.should == 1
308
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
309
+ @new_brazil_programmer.projects.size.should == 2
310
+ end
311
+
312
+ it "length" do
313
+ @new_brazil_programmer.projects.length.should == 0
314
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
315
+ @new_brazil_programmer.projects.length.should == 1
316
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
317
+ @new_brazil_programmer.projects.length.should == 2
318
+ end
319
+
320
+
321
+ it "empty?" do
322
+ @new_brazil_programmer.projects.empty?.should be_true
323
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
324
+ @new_brazil_programmer.projects.empty?.should be_false
325
+ end
326
+
327
+ it "delete_all" do
328
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
329
+ @new_brazil_programmer.projects.empty?.should be_false
330
+ @new_brazil_programmer.projects.delete_all
331
+ @new_brazil_programmer.projects.empty?.should be_true
332
+ end
333
+
334
+ it "destroy_all" do
335
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
336
+ @new_brazil_programmer.projects.empty?.should be_false
337
+ @new_brazil_programmer.projects.destroy_all
338
+ @new_brazil_programmer.projects.empty?.should be_true
339
+ end
340
+
341
+ it "find" do
342
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
343
+ @new_brazil_programmer.projects.find(:first).should == role
344
+ @new_brazil_programmer.projects.destroy_all
345
+ @new_brazil_programmer.projects.find(:first).should be_nil
346
+ end
347
+
348
+ it "exists?" do
349
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
350
+ @new_brazil_programmer.projects.exists?(role).should be_true
351
+ @new_brazil_programmer.projects.destroy_all
352
+ @new_brazil_programmer.projects.exists?(role).should be_false
353
+ end
354
+
355
+ it "clear" do
356
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
357
+ @new_brazil_programmer.projects.empty?.should be_false
358
+ @new_brazil_programmer.projects.clear
359
+ @new_brazil_programmer.projects.empty?.should be_true
360
+ end
361
+
362
+ it "delete" do
363
+ role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
364
+ @new_brazil_programmer.projects.empty?.should be_false
365
+ @new_brazil_programmer.projects.delete(role)
366
+ @new_brazil_programmer.reload
367
+ @project.reload
368
+ @project.programmers.should == []
369
+ @new_brazil_programmer.projects.should == []
370
+ end
371
+ end
372
+ end
373
+
374
+ describe "when you have a 1 x N relationship" do
375
+ before(:each) do
376
+ @brazil_client = Client.using(:brazil).create!(:name => "Brazil Client")
377
+ @master_client = Client.create!(:name => "Master Client")
378
+ @item_brazil = Item.using(:brazil).create!(:name => "Brazil Item", :client => @brazil_client)
379
+ @item_master = Item.create!(:name => "Master Item", :client => @master_client)
380
+ @brazil_client = Client.using(:brazil).find_by_name("Brazil Client")
381
+ Client.using(:master).create!(:name => "teste")
382
+ end
383
+
384
+ it "should find all models in the specified shard" do
385
+ @brazil_client.item_ids.should == [@item_brazil.id]
386
+ @brazil_client.items().should == [@item_brazil]
387
+ end
388
+
389
+ it "should finds the client that the item belongs" do
390
+ @item_brazil.client.should == @brazil_client
391
+ end
392
+
393
+ it "should update the attribute for the item" do
394
+ new_brazil_client = Client.using(:brazil).create!(:name => "new Client")
395
+ @item_brazil.client = new_brazil_client
396
+ @item_brazil.client.should == new_brazil_client
397
+ @item_brazil.save()
398
+ @item_brazil.reload
399
+ @item_brazil.client_id.should == new_brazil_client.id
400
+ @item_brazil.client().should == new_brazil_client
401
+ end
402
+
403
+ it "should works for build method" do
404
+ item2 = Item.using(:brazil).create!(:name => "Brazil Item")
405
+ c = item2.create_client(:name => "new Client")
406
+ c.save()
407
+ item2.save()
408
+ item2.client.should == c
409
+ c.items().should == [item2]
410
+ end
411
+
412
+ describe "it should works when using" do
413
+ before(:each) do
414
+ @item_brazil_2 = Item.using(:brazil).create!(:name => "Brazil Item 2")
415
+ @brazil_client.items.to_set.should == [@item_brazil].to_set
416
+ end
417
+
418
+ it "update_attributes" do
419
+ @brazil_client.update_attributes(:item_ids => [@item_brazil_2.id, @item_brazil.id])
420
+ @brazil_client.items.to_set.should == [@item_brazil, @item_brazil_2].to_set
421
+ end
422
+
423
+ it "update_attribute" do
424
+ @brazil_client.update_attribute(:item_ids, [@item_brazil_2.id, @item_brazil.id])
425
+ @brazil_client.items.to_set.should == [@item_brazil, @item_brazil_2].to_set
426
+ end
427
+
428
+ it "<<" do
429
+ @brazil_client.items << @item_brazil_2
430
+ @brazil_client.items.to_set.should == [@item_brazil, @item_brazil_2].to_set
431
+ end
432
+
433
+ it "build" do
434
+ item = @brazil_client.items.build(:name => "Builded Item")
435
+ item.save()
436
+ @brazil_client.items.to_set.should == [@item_brazil, item].to_set
437
+ end
438
+
439
+ it "create" do
440
+ item = @brazil_client.items.create(:name => "Builded Item")
441
+ @brazil_client.items.to_set.should == [@item_brazil, item].to_set
442
+ end
443
+
444
+ it "count" do
445
+ @brazil_client.items.count.should == 1
446
+ item = @brazil_client.items.create(:name => "Builded Item")
447
+ @brazil_client.items.count.should == 2
448
+ end
449
+
450
+ it "size" do
451
+ @brazil_client.items.size.should == 1
452
+ item = @brazil_client.items.create(:name => "Builded Item")
453
+ @brazil_client.items.size.should == 2
454
+ end
455
+
456
+ it "create!" do
457
+ item = @brazil_client.items.create!(:name => "Builded Item")
458
+ @brazil_client.items.to_set.should == [@item_brazil, item].to_set
459
+ end
460
+
461
+ it "length" do
462
+ @brazil_client.items.length.should == 1
463
+ item = @brazil_client.items.create(:name => "Builded Item")
464
+ @brazil_client.items.length.should == 2
465
+ end
466
+
467
+ it "empty?" do
468
+ @brazil_client.items.empty?.should be_false
469
+ c = Client.create!(:name => "Client1")
470
+ c.items.empty?.should be_true
471
+ end
472
+
473
+ it "delete" do
474
+ @brazil_client.items.empty?.should be_false
475
+ @brazil_client.items.delete(@item_brazil)
476
+ @brazil_client.reload
477
+ @item_brazil.reload
478
+ @item_brazil.client.should be_nil
479
+ @brazil_client.items.should == []
480
+ @brazil_client.items.empty?.should be_true
481
+ end
482
+
483
+ it "delete_all" do
484
+ @brazil_client.items.empty?.should be_false
485
+ @brazil_client.items.delete_all
486
+ @brazil_client.items.empty?.should be_true
487
+ end
488
+
489
+ it "destroy_all" do
490
+ @brazil_client.items.empty?.should be_false
491
+ @brazil_client.items.destroy_all
492
+ @brazil_client.items.empty?.should be_true
493
+ end
494
+
495
+ it "find" do
496
+ @brazil_client.items.find(:first).should == @item_brazil
497
+ @brazil_client.items.destroy_all
498
+ @brazil_client.items.find(:first).should be_nil
499
+ end
500
+
501
+ it "exists?" do
502
+ @brazil_client.items.exists?(@item_brazil).should be_true
503
+ @brazil_client.items.destroy_all
504
+ @brazil_client.items.exists?(@item_brazil).should be_false
505
+ end
506
+
507
+ it "uniq" do
508
+ @brazil_client.items.uniq.should == [@item_brazil]
509
+ end
510
+
511
+ it "clear" do
512
+ @brazil_client.items.empty?.should be_false
513
+ @brazil_client.items.clear
514
+ @brazil_client.items.empty?.should be_true
515
+ end
516
+ end
517
+ end
518
+ end