low_card_tables 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +59 -0
  4. data/Gemfile +17 -0
  5. data/LICENSE +21 -0
  6. data/README.md +75 -0
  7. data/Rakefile +6 -0
  8. data/lib/low_card_tables.rb +72 -0
  9. data/lib/low_card_tables/active_record/base.rb +55 -0
  10. data/lib/low_card_tables/active_record/migrations.rb +223 -0
  11. data/lib/low_card_tables/active_record/relation.rb +35 -0
  12. data/lib/low_card_tables/active_record/scoping.rb +87 -0
  13. data/lib/low_card_tables/errors.rb +74 -0
  14. data/lib/low_card_tables/has_low_card_table/base.rb +114 -0
  15. data/lib/low_card_tables/has_low_card_table/low_card_association.rb +273 -0
  16. data/lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb +143 -0
  17. data/lib/low_card_tables/has_low_card_table/low_card_dynamic_method_manager.rb +224 -0
  18. data/lib/low_card_tables/has_low_card_table/low_card_objects_manager.rb +80 -0
  19. data/lib/low_card_tables/low_card_table/base.rb +184 -0
  20. data/lib/low_card_tables/low_card_table/cache.rb +214 -0
  21. data/lib/low_card_tables/low_card_table/cache_expiration/exponential_cache_expiration_policy.rb +151 -0
  22. data/lib/low_card_tables/low_card_table/cache_expiration/fixed_cache_expiration_policy.rb +23 -0
  23. data/lib/low_card_tables/low_card_table/cache_expiration/has_cache_expiration.rb +100 -0
  24. data/lib/low_card_tables/low_card_table/cache_expiration/no_caching_expiration_policy.rb +13 -0
  25. data/lib/low_card_tables/low_card_table/cache_expiration/unlimited_cache_expiration_policy.rb +13 -0
  26. data/lib/low_card_tables/low_card_table/row_collapser.rb +175 -0
  27. data/lib/low_card_tables/low_card_table/row_manager.rb +681 -0
  28. data/lib/low_card_tables/low_card_table/table_unique_index.rb +134 -0
  29. data/lib/low_card_tables/version.rb +4 -0
  30. data/lib/low_card_tables/version_support.rb +52 -0
  31. data/low_card_tables.gemspec +69 -0
  32. data/spec/low_card_tables/helpers/database_helper.rb +148 -0
  33. data/spec/low_card_tables/helpers/query_spy_helper.rb +47 -0
  34. data/spec/low_card_tables/helpers/system_helpers.rb +63 -0
  35. data/spec/low_card_tables/system/basic_system_spec.rb +254 -0
  36. data/spec/low_card_tables/system/bulk_system_spec.rb +334 -0
  37. data/spec/low_card_tables/system/caching_system_spec.rb +531 -0
  38. data/spec/low_card_tables/system/migrations_system_spec.rb +747 -0
  39. data/spec/low_card_tables/system/options_system_spec.rb +581 -0
  40. data/spec/low_card_tables/system/queries_system_spec.rb +142 -0
  41. data/spec/low_card_tables/system/validations_system_spec.rb +88 -0
  42. data/spec/low_card_tables/unit/active_record/base_spec.rb +53 -0
  43. data/spec/low_card_tables/unit/active_record/migrations_spec.rb +207 -0
  44. data/spec/low_card_tables/unit/active_record/relation_spec.rb +47 -0
  45. data/spec/low_card_tables/unit/active_record/scoping_spec.rb +101 -0
  46. data/spec/low_card_tables/unit/has_low_card_table/base_spec.rb +79 -0
  47. data/spec/low_card_tables/unit/has_low_card_table/low_card_association_spec.rb +287 -0
  48. data/spec/low_card_tables/unit/has_low_card_table/low_card_associations_manager_spec.rb +190 -0
  49. data/spec/low_card_tables/unit/has_low_card_table/low_card_dynamic_method_manager_spec.rb +234 -0
  50. data/spec/low_card_tables/unit/has_low_card_table/low_card_objects_manager_spec.rb +70 -0
  51. data/spec/low_card_tables/unit/low_card_table/base_spec.rb +207 -0
  52. data/spec/low_card_tables/unit/low_card_table/cache_expiration/exponential_cache_expiration_policy_spec.rb +128 -0
  53. data/spec/low_card_tables/unit/low_card_table/cache_expiration/fixed_cache_expiration_policy_spec.rb +25 -0
  54. data/spec/low_card_tables/unit/low_card_table/cache_expiration/has_cache_expiration_policy_spec.rb +100 -0
  55. data/spec/low_card_tables/unit/low_card_table/cache_expiration/no_caching_expiration_policy_spec.rb +14 -0
  56. data/spec/low_card_tables/unit/low_card_table/cache_expiration/unlimited_cache_expiration_policy_spec.rb +14 -0
  57. data/spec/low_card_tables/unit/low_card_table/cache_spec.rb +282 -0
  58. data/spec/low_card_tables/unit/low_card_table/row_collapser_spec.rb +109 -0
  59. data/spec/low_card_tables/unit/low_card_table/row_manager_spec.rb +918 -0
  60. data/spec/low_card_tables/unit/low_card_table/table_unique_index_spec.rb +117 -0
  61. metadata +206 -0
@@ -0,0 +1,581 @@
1
+ require 'low_card_tables'
2
+ require 'low_card_tables/helpers/database_helper'
3
+ require 'low_card_tables/helpers/system_helpers'
4
+
5
+ describe "LowCardTables association options" do
6
+ include LowCardTables::Helpers::SystemHelpers
7
+
8
+ before :each do
9
+ @dh = LowCardTables::Helpers::DatabaseHelper.new
10
+ @dh.setup_activerecord!
11
+ end
12
+
13
+ it "should exclude any columns marked with :exclude_column_names" do
14
+ migrate do
15
+ drop_table :lctables_spec_user_statuses rescue nil
16
+ create_table :lctables_spec_user_statuses do |t|
17
+ t.boolean :deleted, :null => false
18
+ t.boolean :deceased
19
+ t.string :gender, :null => false
20
+ t.integer :donation_level
21
+ end
22
+
23
+ add_index :lctables_spec_user_statuses, [ :deleted, :deceased, :gender ], :unique => true, :name => 'index_lctables_spec_user_statuses_on_all'
24
+
25
+ drop_table :lctables_spec_users rescue nil
26
+ create_table :lctables_spec_users do |t|
27
+ t.string :name, :null => false
28
+ t.integer :user_status_id, :null => false, :limit => 2
29
+ end
30
+ end
31
+
32
+ define_model_class(:UserStatusExcludeColumnNames, :lctables_spec_user_statuses) do
33
+ is_low_card_table :exclude_column_names => [ :donation_level ]
34
+ end
35
+
36
+ define_model_class(:UserExcludeColumnNames, :lctables_spec_users) do
37
+ has_low_card_table :status, :class => :UserStatusExcludeColumnNames, :foreign_key => :user_status_id
38
+ end
39
+
40
+ ::UserStatusExcludeColumnNames.count.should == 0
41
+
42
+ user1 = ::UserExcludeColumnNames.new
43
+ user1.name = 'User1'
44
+ user1.deleted = false
45
+ user1.deceased = false
46
+ user1.gender = 'female'
47
+ user1.status.donation_level = 15
48
+
49
+ user1.respond_to?(:donation_level).should_not be
50
+ user1.save!
51
+
52
+ ::UserStatusExcludeColumnNames.count.should == 1
53
+ ::UserStatusExcludeColumnNames.first.donation_level.should be_nil
54
+ ::UserStatusExcludeColumnNames.update_all("donation_level = 35")
55
+
56
+ user2 = ::UserExcludeColumnNames.new
57
+ user2.name = 'User2'
58
+ user2.deleted = false
59
+ user2.deceased = false
60
+ user2.gender = 'female'
61
+ user2.status.donation_level = 27
62
+
63
+ user2.save!
64
+
65
+ user1.user_status_id.should == user2.user_status_id
66
+ ::UserStatusExcludeColumnNames.count.should == 1
67
+ ::UserStatusExcludeColumnNames.first.donation_level.should == 35
68
+ end
69
+
70
+ it "should exclude :created_at and :updated_at by default, but use them" do
71
+ migrate do
72
+ drop_table :lctables_spec_user_statuses rescue nil
73
+ create_table :lctables_spec_user_statuses do |t|
74
+ t.boolean :deleted, :null => false
75
+ t.boolean :deceased
76
+ t.string :gender, :null => false
77
+
78
+ t.timestamps
79
+ end
80
+
81
+ add_index :lctables_spec_user_statuses, [ :deleted, :deceased, :gender ], :unique => true, :name => 'index_lctables_spec_user_statuses_on_all'
82
+
83
+ drop_table :lctables_spec_users rescue nil
84
+ create_table :lctables_spec_users do |t|
85
+ t.string :name, :null => false
86
+ t.integer :user_status_id, :null => false, :limit => 2
87
+ end
88
+ end
89
+
90
+ define_model_class(:UserStatusExcludeCreatedUpdated, :lctables_spec_user_statuses) { is_low_card_table }
91
+
92
+ define_model_class(:UserExcludeCreatedUpdated, :lctables_spec_users) do
93
+ has_low_card_table :status, :class => :UserStatusExcludeCreatedUpdated, :foreign_key => :user_status_id
94
+ end
95
+
96
+ ::UserStatusExcludeCreatedUpdated.count.should == 0
97
+
98
+ user1 = ::UserExcludeCreatedUpdated.new
99
+ user1.name = 'User1'
100
+ user1.deleted = false
101
+ user1.deceased = false
102
+ user1.gender = 'female'
103
+
104
+ start_time = Time.now.to_i
105
+ user1.save!
106
+ end_time = Time.now.to_i
107
+
108
+ ::UserStatusExcludeCreatedUpdated.count.should == 1
109
+ ::UserStatusExcludeCreatedUpdated.first.created_at.to_i.should >= start_time
110
+ ::UserStatusExcludeCreatedUpdated.first.created_at.to_i.should <= end_time
111
+ ::UserStatusExcludeCreatedUpdated.first.updated_at.to_i.should >= start_time
112
+ ::UserStatusExcludeCreatedUpdated.first.updated_at.to_i.should <= end_time
113
+
114
+ user2 = ::UserExcludeCreatedUpdated.new
115
+ user2.name = 'User2'
116
+ user2.deleted = false
117
+ user2.deceased = false
118
+ user2.gender = 'female'
119
+
120
+ user2.save!
121
+
122
+ user1.user_status_id.should == user2.user_status_id
123
+ ::UserStatusExcludeCreatedUpdated.count.should == 1
124
+ ::UserStatusExcludeCreatedUpdated.first.created_at.to_i.should >= start_time
125
+ ::UserStatusExcludeCreatedUpdated.first.created_at.to_i.should <= end_time
126
+ ::UserStatusExcludeCreatedUpdated.first.updated_at.to_i.should >= start_time
127
+ ::UserStatusExcludeCreatedUpdated.first.updated_at.to_i.should <= end_time
128
+ end
129
+ context "with standard setup" do
130
+ before :each do
131
+ create_standard_system_spec_tables!
132
+ create_standard_system_spec_models!
133
+ end
134
+
135
+ after :each do
136
+ drop_standard_system_spec_tables!
137
+ end
138
+
139
+ it "should allow multiple references from a table to the same low-card table, and method delegation should be from the last one added" do
140
+ migrate do
141
+ add_column :lctables_spec_users, :old_user_status_id, :integer
142
+ end
143
+
144
+ ::User.reset_column_information
145
+ class ::User < ::ActiveRecord::Base
146
+ has_low_card_table :old_status, :class => ::UserStatus, :foreign_key => :old_user_status_id
147
+ end
148
+
149
+ user1 = ::User.new
150
+
151
+ user1.name = 'User1'
152
+
153
+ user1.deleted = false
154
+ user1.deceased = false
155
+ user1.gender = 'female'
156
+ user1.donation_level = 8
157
+
158
+ user1.status.deleted = true
159
+ user1.status.deceased = false
160
+ user1.status.gender = 'male'
161
+ user1.status.donation_level = 3
162
+
163
+ user1.save!
164
+
165
+ user1.user_status_id.should_not == user1.old_user_status_id
166
+
167
+ user1_again = ::User.find(user1.id)
168
+
169
+ user1_again.user_status_id.should == user1.user_status_id
170
+ user1_again.old_user_status_id.should == user1.old_user_status_id
171
+
172
+ user1_again.status.deleted.should == true
173
+ user1_again.status.deceased.should == false
174
+ user1_again.status.gender.should == 'male'
175
+ user1_again.status.donation_level.should == 3
176
+
177
+ user1_again.old_status.deleted.should == false
178
+ user1_again.old_status.deceased.should == false
179
+ user1_again.old_status.gender.should == 'female'
180
+ user1_again.old_status.donation_level.should == 8
181
+ end
182
+
183
+ it "should not blow away methods that are already there, in the class itself, but still allow calls to super" do
184
+ define_model_class(:UserTest, :lctables_spec_users) do
185
+ def deleted
186
+ [ @_other_deleted, super ]
187
+ end
188
+
189
+ def deleted=(x)
190
+ @_other_deleted ||= [ ]
191
+ @_other_deleted << x
192
+ super(x)
193
+ end
194
+
195
+ has_low_card_table :status, :class => ::UserStatus, :foreign_key => :user_status_id
196
+ end
197
+
198
+ user1 = ::UserTest.new
199
+
200
+ user1.deleted.should == [ nil, nil ]
201
+ user1.deleted = true
202
+ user1.deleted.should == [ [ true ], true ]
203
+ user1.deleted = false
204
+ user1.deleted.should == [ [ true, false ], false ]
205
+ end
206
+
207
+ it "should override methods defined in a superclass" do
208
+ class RandomSuperclass < ::ActiveRecord::Base
209
+ self.table_name = :lctables_spec_users
210
+
211
+ def deleted
212
+ raise "should never run"
213
+ end
214
+
215
+ def deleted=(x)
216
+ raise "should never run"
217
+ end
218
+ end
219
+
220
+ class UserTest1 < RandomSuperclass
221
+ has_low_card_table :status, :class => ::UserStatus, :foreign_key => :user_status_id
222
+ end
223
+
224
+ user1 = ::UserTest1.new
225
+ user1.name = 'User1'
226
+
227
+ user1.deleted.should == nil
228
+ user1.deleted = true
229
+ user1.deleted.should == true
230
+ user1.deceased = false
231
+ user1.gender = 'female'
232
+ user1.donation_level = 10
233
+ user1.save!
234
+
235
+ user1.deleted.should == true
236
+ user1.deleted = false
237
+ user1.deleted.should == false
238
+ user1.save!
239
+
240
+ user1.deleted.should == false
241
+ end
242
+
243
+ it "should override methods defined in a module, when included before" do
244
+ module RandomModule
245
+ def deleted
246
+ raise "should never run"
247
+ end
248
+
249
+ def deleted=(x)
250
+ raise "should never run"
251
+ end
252
+ end
253
+
254
+ class UserTest2 < ::ActiveRecord::Base
255
+ include RandomModule
256
+
257
+ self.table_name = :lctables_spec_users
258
+ has_low_card_table :status, :class => ::UserStatus, :foreign_key => :user_status_id
259
+ end
260
+
261
+ user1 = ::UserTest2.new
262
+ user1.name = 'User1'
263
+
264
+ user1.deleted.should == nil
265
+ user1.deleted = true
266
+ user1.deleted.should == true
267
+ user1.deceased = false
268
+ user1.gender = 'female'
269
+ user1.donation_level = 10
270
+ user1.save!
271
+
272
+ user1.deleted.should == true
273
+ user1.deleted = false
274
+ user1.deleted.should == false
275
+ user1.save!
276
+
277
+ user1.deleted.should == false
278
+ end
279
+
280
+ it "should not override methods defined in a module, when included after" do
281
+ module RandomModule
282
+ def deleted
283
+ "foo#{@_deleted}"
284
+ end
285
+
286
+ def deleted=(x)
287
+ @_deleted = x
288
+ end
289
+ end
290
+
291
+ class UserTest3 < ::ActiveRecord::Base
292
+ self.table_name = :lctables_spec_users
293
+ has_low_card_table :status, :class => ::UserStatus, :foreign_key => :user_status_id
294
+
295
+ include RandomModule
296
+ end
297
+
298
+ user1 = ::UserTest3.new
299
+ user1.name = 'User1'
300
+
301
+ user1.deleted.should == 'foo'
302
+ user1.deleted = 'bar'
303
+ user1.deleted.should == 'foobar'
304
+ end
305
+
306
+ it "should allow prefixing delegated methods with the association name easily" do
307
+ define_model_class(:User, :lctables_spec_users) { has_low_card_table :status, :prefix => true }
308
+
309
+ user1 = ::User.new
310
+ user1.name = 'User1'
311
+
312
+ lambda { user1.deleted }.should raise_error(NoMethodError)
313
+ lambda { user1.deceased }.should raise_error(NoMethodError)
314
+ lambda { user1.gender }.should raise_error(NoMethodError)
315
+ lambda { user1.donation_level }.should raise_error(NoMethodError)
316
+ lambda { user1.deleted = true }.should raise_error(NoMethodError)
317
+ lambda { user1.deceased = true }.should raise_error(NoMethodError)
318
+ lambda { user1.gender = 'male' }.should raise_error(NoMethodError)
319
+ lambda { user1.donation_level = 10 }.should raise_error(NoMethodError)
320
+
321
+ user1.status_deleted = true
322
+ user1.status_deceased = false
323
+ user1.status_gender = 'female'
324
+ user1.status_donation_level = 10
325
+
326
+ user1.save!
327
+
328
+ user1.status_deleted.should == true
329
+ user1.status_deceased.should == false
330
+ user1.status_gender.should == 'female'
331
+ user1.status_donation_level.should == 10
332
+
333
+ user1.status.deleted.should == true
334
+ user1.status.deceased.should == false
335
+ user1.status.gender.should == 'female'
336
+ user1.status.donation_level.should == 10
337
+ end
338
+
339
+ %w{symbol string}.each do |prefix_type|
340
+ it "should allow prefixing delegated methods with any arbitrary #{prefix_type}" do
341
+ prefix = 'foo'
342
+ prefix = prefix.to_sym if prefix_type == 'symbol'
343
+ define_model_class(:User, :lctables_spec_users) { has_low_card_table :status, :prefix => prefix }
344
+
345
+ user1 = ::User.new
346
+ user1.name = 'User1'
347
+
348
+ lambda { user1.deleted }.should raise_error(NoMethodError)
349
+ lambda { user1.deceased }.should raise_error(NoMethodError)
350
+ lambda { user1.gender }.should raise_error(NoMethodError)
351
+ lambda { user1.donation_level }.should raise_error(NoMethodError)
352
+ lambda { user1.deleted = true }.should raise_error(NoMethodError)
353
+ lambda { user1.deceased = true }.should raise_error(NoMethodError)
354
+ lambda { user1.gender = 'male' }.should raise_error(NoMethodError)
355
+ lambda { user1.donation_level = 10 }.should raise_error(NoMethodError)
356
+
357
+ user1.foo_deleted = true
358
+ user1.foo_deceased = false
359
+ user1.foo_gender = 'female'
360
+ user1.foo_donation_level = 10
361
+
362
+ user1.save!
363
+
364
+ user1.foo_deleted.should == true
365
+ user1.foo_deceased.should == false
366
+ user1.foo_gender.should == 'female'
367
+ user1.foo_donation_level.should == 10
368
+
369
+ user1.status.deleted.should == true
370
+ user1.status.deceased.should == false
371
+ user1.status.gender.should == 'female'
372
+ user1.status.donation_level.should == 10
373
+ end
374
+ end
375
+
376
+ it "should allow defining an association twice, and the second one should win" do
377
+ define_model_class(:User, :lctables_spec_users) do
378
+ has_low_card_table :status
379
+ has_low_card_table :status, :prefix => :foo
380
+ end
381
+
382
+ user1 = ::User.new
383
+ user1.name = 'User1'
384
+
385
+ lambda { user1.deleted }.should raise_error(NoMethodError)
386
+ lambda { user1.deceased }.should raise_error(NoMethodError)
387
+ lambda { user1.gender }.should raise_error(NoMethodError)
388
+ lambda { user1.donation_level }.should raise_error(NoMethodError)
389
+ lambda { user1.deleted = true }.should raise_error(NoMethodError)
390
+ lambda { user1.deceased = true }.should raise_error(NoMethodError)
391
+ lambda { user1.gender = 'male' }.should raise_error(NoMethodError)
392
+ lambda { user1.donation_level = 10 }.should raise_error(NoMethodError)
393
+
394
+ user1.foo_deleted = true
395
+ user1.foo_deceased = false
396
+ user1.foo_gender = 'female'
397
+ user1.foo_donation_level = 10
398
+
399
+ user1.save!
400
+
401
+ user1.foo_deleted.should == true
402
+ user1.foo_deceased.should == false
403
+ user1.foo_gender.should == 'female'
404
+ user1.foo_donation_level.should == 10
405
+
406
+ user1.status.deleted.should == true
407
+ user1.status.deceased.should == false
408
+ user1.status.gender.should == 'female'
409
+ user1.status.donation_level.should == 10
410
+ end
411
+
412
+ it "should allow delegating no methods from the has_low_card_table class" do
413
+ define_model_class(:User, :lctables_spec_users) { has_low_card_table :status, :delegate => false }
414
+
415
+ user1 = ::User.new
416
+ user1.name = 'User1'
417
+
418
+ lambda { user1.deleted }.should raise_error(NoMethodError)
419
+ lambda { user1.deceased }.should raise_error(NoMethodError)
420
+ lambda { user1.gender }.should raise_error(NoMethodError)
421
+ lambda { user1.donation_level }.should raise_error(NoMethodError)
422
+ lambda { user1.deleted = true }.should raise_error(NoMethodError)
423
+ lambda { user1.deceased = true }.should raise_error(NoMethodError)
424
+ lambda { user1.gender = 'male' }.should raise_error(NoMethodError)
425
+ lambda { user1.donation_level = 10 }.should raise_error(NoMethodError)
426
+
427
+ user1.status.deleted = true
428
+ user1.status.deceased = false
429
+ user1.status.gender = 'female'
430
+ user1.status.donation_level = 10
431
+
432
+ user1.save!
433
+
434
+ user1.status.deleted.should == true
435
+ user1.status.deceased.should == false
436
+ user1.status.gender.should == 'female'
437
+ user1.status.donation_level.should == 10
438
+ end
439
+
440
+ it "should allow delegating just specified methods from the has_low_card_table class" do
441
+ define_model_class(:User, :lctables_spec_users) { has_low_card_table :status, :delegate => [ 'deleted', :gender ] }
442
+
443
+ user1 = ::User.new
444
+ user1.name = 'User1'
445
+
446
+ lambda { user1.deceased }.should raise_error(NoMethodError)
447
+ lambda { user1.donation_level }.should raise_error(NoMethodError)
448
+ lambda { user1.deceased = true }.should raise_error(NoMethodError)
449
+ lambda { user1.donation_level = 10 }.should raise_error(NoMethodError)
450
+
451
+ user1.deleted = true
452
+ user1.status.deceased = false
453
+ user1.gender = 'female'
454
+ user1.status.donation_level = 10
455
+
456
+ user1.save!
457
+
458
+ user1.deleted.should == true
459
+ user1.status.deleted.should == true
460
+ user1.status.deceased.should == false
461
+ user1.gender.should == 'female'
462
+ user1.status.gender.should == 'female'
463
+ user1.status.donation_level.should == 10
464
+ end
465
+
466
+ it "should allow delegating all methods from the has_low_card_table class except what's excluded" do
467
+ define_model_class(:User, :lctables_spec_users) { has_low_card_table :status, :delegate => { :except => [ 'deceased', :donation_level ] } }
468
+
469
+ user1 = ::User.new
470
+ user1.name = 'User1'
471
+
472
+ lambda { user1.deceased }.should raise_error(NoMethodError)
473
+ lambda { user1.donation_level }.should raise_error(NoMethodError)
474
+ lambda { user1.deceased = true }.should raise_error(NoMethodError)
475
+ lambda { user1.donation_level = 10 }.should raise_error(NoMethodError)
476
+
477
+ user1.deleted = true
478
+ user1.status.deceased = false
479
+ user1.gender = 'female'
480
+ user1.status.donation_level = 10
481
+
482
+ user1.save!
483
+
484
+ user1.deleted.should == true
485
+ user1.status.deleted.should == true
486
+ user1.status.deceased.should == false
487
+ user1.gender.should == 'female'
488
+ user1.status.gender.should == 'female'
489
+ user1.status.donation_level.should == 10
490
+ end
491
+
492
+ it "should blow up if asked to delegate or exclude methods that aren't there" do
493
+ e = nil
494
+ begin
495
+ define_model_class(:User, :lctables_spec_users) { has_low_card_table :status, :delegate => [ :foo ] }
496
+ rescue ArgumentError => x
497
+ e = x
498
+ end
499
+
500
+ e.message.should match(/foo/mi)
501
+ e.message.should match(/deleted/mi)
502
+ e.message.should match(/deceased/mi)
503
+ e.message.should match(/gender/mi)
504
+ e.message.should match(/donation_level/mi)
505
+
506
+ e = nil
507
+ begin
508
+ define_model_class(:User, :lctables_spec_users) { has_low_card_table :status, :delegate => { :except => [ :foo ] } }
509
+ rescue ArgumentError => x
510
+ e = x
511
+ end
512
+
513
+ e.message.should match(/foo/mi)
514
+ e.message.should match(/deleted/mi)
515
+ e.message.should match(/deceased/mi)
516
+ e.message.should match(/gender/mi)
517
+ e.message.should match(/donation_level/mi)
518
+ end
519
+
520
+ it "should combine :prefix and :delegate correctly" do
521
+ define_model_class(:User, :lctables_spec_users) { has_low_card_table :status, :prefix => :foo, :delegate => { :except => [ 'deceased', :donation_level ] } }
522
+
523
+ user1 = ::User.new
524
+ user1.name = 'User1'
525
+
526
+ lambda { user1.foo_deceased }.should raise_error(NoMethodError)
527
+ lambda { user1.foo_donation_level }.should raise_error(NoMethodError)
528
+ lambda { user1.foo_deceased = true }.should raise_error(NoMethodError)
529
+ lambda { user1.foo_donation_level = 10 }.should raise_error(NoMethodError)
530
+
531
+ user1.foo_deleted = true
532
+ user1.status.deceased = false
533
+ user1.foo_gender = 'female'
534
+ user1.status.donation_level = 10
535
+
536
+ user1.save!
537
+
538
+ user1.foo_deleted.should == true
539
+ user1.status.deleted.should == true
540
+ user1.status.deceased.should == false
541
+ user1.foo_gender.should == 'female'
542
+ user1.status.gender.should == 'female'
543
+ user1.status.donation_level.should == 10
544
+ end
545
+
546
+ %w{symbol string class}.each do |specification_type|
547
+ it "should allow specifying the target class manually as a #{specification_type}, and the foreign key manually" do
548
+ define_model_class(:Foobar, :lctables_spec_user_statuses) { is_low_card_table }
549
+
550
+ specification = case specification_type
551
+ when 'symbol' then :Foobar
552
+ when 'string' then 'Foobar'
553
+ when 'class' then Foobar
554
+ else raise "Unknown specification_type: #{specification_type.inspect}"
555
+ end
556
+
557
+ define_model_class(:Barbaz, :lctables_spec_users) { has_low_card_table :status, :class => specification, :foreign_key => :user_status_id }
558
+
559
+ user1 = ::Barbaz.new
560
+
561
+ user1.name = 'User1'
562
+
563
+ user1.deleted = false
564
+ user1.deceased = false
565
+ user1.gender = 'female'
566
+ user1.donation_level = 8
567
+
568
+ user1.save!
569
+
570
+ user1_again = ::Barbaz.find(user1.id)
571
+
572
+ user1_again.user_status_id.should == user1.user_status_id
573
+
574
+ user1_again.status.deleted.should == false
575
+ user1_again.status.deceased.should == false
576
+ user1_again.status.gender.should == 'female'
577
+ user1_again.status.donation_level.should == 8
578
+ end
579
+ end
580
+ end
581
+ end