activerecord 1.10.1 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- data/CHANGELOG +187 -19
- data/RUNNING_UNIT_TESTS +11 -0
- data/lib/active_record.rb +3 -1
- data/lib/active_record/acts/list.rb +25 -14
- data/lib/active_record/acts/nested_set.rb +4 -4
- data/lib/active_record/acts/tree.rb +18 -1
- data/lib/active_record/associations.rb +90 -17
- data/lib/active_record/associations/association_collection.rb +44 -5
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +17 -4
- data/lib/active_record/associations/has_many_association.rb +13 -3
- data/lib/active_record/associations/has_one_association.rb +19 -0
- data/lib/active_record/base.rb +292 -268
- data/lib/active_record/callbacks.rb +14 -14
- data/lib/active_record/connection_adapters/abstract_adapter.rb +137 -75
- data/lib/active_record/connection_adapters/db2_adapter.rb +10 -8
- data/lib/active_record/connection_adapters/mysql_adapter.rb +91 -64
- data/lib/active_record/connection_adapters/oci_adapter.rb +6 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +113 -60
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +15 -12
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +159 -132
- data/lib/active_record/fixtures.rb +59 -12
- data/lib/active_record/locking.rb +10 -9
- data/lib/active_record/migration.rb +112 -5
- data/lib/active_record/query_cache.rb +64 -0
- data/lib/active_record/timestamp.rb +10 -8
- data/lib/active_record/validations.rb +121 -26
- data/rakefile +16 -10
- data/test/aaa_create_tables_test.rb +26 -48
- data/test/abstract_unit.rb +3 -0
- data/test/aggregations_test.rb +19 -19
- data/test/association_callbacks_test.rb +110 -0
- data/test/associations_go_eager_test.rb +48 -14
- data/test/associations_test.rb +344 -142
- data/test/base_test.rb +150 -31
- data/test/binary_test.rb +7 -0
- data/test/callbacks_test.rb +24 -5
- data/test/column_alias_test.rb +2 -2
- data/test/connections/native_sqlserver_odbc/connection.rb +26 -0
- data/test/deprecated_associations_test.rb +27 -28
- data/test/deprecated_finder_test.rb +8 -9
- data/test/finder_test.rb +52 -17
- data/test/fixtures/author.rb +39 -0
- data/test/fixtures/categories.yml +7 -0
- data/test/fixtures/categories_posts.yml +8 -0
- data/test/fixtures/category.rb +2 -0
- data/test/fixtures/comment.rb +3 -1
- data/test/fixtures/comments.yml +43 -1
- data/test/fixtures/companies.yml +14 -0
- data/test/fixtures/company.rb +1 -1
- data/test/fixtures/computers.yml +2 -1
- data/test/fixtures/db_definitions/db2.sql +7 -2
- data/test/fixtures/db_definitions/mysql.drop.sql +2 -0
- data/test/fixtures/db_definitions/mysql.sql +11 -6
- data/test/fixtures/db_definitions/oci.sql +7 -2
- data/test/fixtures/db_definitions/postgresql.drop.sql +3 -1
- data/test/fixtures/db_definitions/postgresql.sql +8 -5
- data/test/fixtures/db_definitions/sqlite.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlite.sql +9 -4
- data/test/fixtures/db_definitions/sqlserver.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlserver.sql +12 -7
- data/test/fixtures/developer.rb +8 -1
- data/test/fixtures/migrations/3_innocent_jointable.rb +12 -0
- data/test/fixtures/post.rb +8 -2
- data/test/fixtures/posts.yml +21 -0
- data/test/fixtures/project.rb +14 -1
- data/test/fixtures/subscriber.rb +3 -0
- data/test/fixtures_test.rb +14 -0
- data/test/inheritance_test.rb +30 -22
- data/test/lifecycle_test.rb +3 -4
- data/test/locking_test.rb +2 -4
- data/test/migration_test.rb +186 -0
- data/test/mixin_nested_set_test.rb +19 -19
- data/test/mixin_test.rb +88 -88
- data/test/modules_test.rb +5 -10
- data/test/multiple_db_test.rb +2 -0
- data/test/pk_test.rb +8 -12
- data/test/reflection_test.rb +8 -4
- data/test/schema_test_postgresql.rb +63 -0
- data/test/thread_safety_test.rb +4 -1
- data/test/transactions_test.rb +9 -2
- data/test/unconnected_test.rb +1 -0
- data/test/validations_test.rb +151 -8
- metadata +11 -5
- data/test/migration_mysql.rb +0 -104
data/test/associations_test.rb
CHANGED
@@ -17,10 +17,8 @@ raise "ActiveRecord should have barked on bad collection keys" unless bad_collec
|
|
17
17
|
|
18
18
|
|
19
19
|
class AssociationsTest < Test::Unit::TestCase
|
20
|
-
|
21
|
-
|
22
|
-
@signals37 = Firm.find(1)
|
23
|
-
end
|
20
|
+
fixtures :accounts, :companies, :developers, :projects, :developers_projects,
|
21
|
+
:computers
|
24
22
|
|
25
23
|
def test_force_reload
|
26
24
|
firm = Firm.new("name" => "A New Firm, Inc")
|
@@ -63,23 +61,20 @@ class AssociationsTest < Test::Unit::TestCase
|
|
63
61
|
end
|
64
62
|
|
65
63
|
class HasOneAssociationsTest < Test::Unit::TestCase
|
66
|
-
|
67
|
-
create_fixtures "accounts", "companies", "developers", "projects", "developers_projects"
|
68
|
-
@signals37 = Firm.find(1)
|
69
|
-
end
|
64
|
+
fixtures :accounts, :companies, :developers, :projects, :developers_projects
|
70
65
|
|
71
66
|
def test_has_one
|
72
|
-
assert_equal
|
73
|
-
assert_equal Account.find(1).credit_limit,
|
67
|
+
assert_equal companies(:first_firm).account, Account.find(1)
|
68
|
+
assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit
|
74
69
|
end
|
75
70
|
|
76
71
|
def test_triple_equality
|
77
|
-
assert Account ===
|
72
|
+
assert Account === companies(:first_firm).account
|
78
73
|
end
|
79
74
|
|
80
75
|
def test_type_mismatch
|
81
|
-
assert_raises(ActiveRecord::AssociationTypeMismatch) {
|
82
|
-
assert_raises(ActiveRecord::AssociationTypeMismatch) {
|
76
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 }
|
77
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) }
|
83
78
|
end
|
84
79
|
|
85
80
|
def test_natural_assignment
|
@@ -90,19 +85,48 @@ class HasOneAssociationsTest < Test::Unit::TestCase
|
|
90
85
|
end
|
91
86
|
|
92
87
|
def test_natural_assignment_to_nil
|
93
|
-
old_account_id =
|
94
|
-
|
95
|
-
|
96
|
-
assert_nil
|
88
|
+
old_account_id = companies(:first_firm).account.id
|
89
|
+
companies(:first_firm).account = nil
|
90
|
+
companies(:first_firm).save
|
91
|
+
assert_nil companies(:first_firm).account
|
97
92
|
# account is dependent, therefore is destroyed when reference to owner is lost
|
98
93
|
assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
|
99
94
|
end
|
95
|
+
|
96
|
+
def test_assignment_without_replacement
|
97
|
+
apple = Firm.create("name" => "Apple")
|
98
|
+
citibank = Account.create("credit_limit" => 10)
|
99
|
+
apple.account = citibank
|
100
|
+
assert_equal apple.id, citibank.firm_id
|
101
|
+
|
102
|
+
hsbc = apple.build_account({ :credit_limit => 20}, false)
|
103
|
+
assert_equal apple.id, hsbc.firm_id
|
104
|
+
hsbc.save
|
105
|
+
assert_equal apple.id, citibank.firm_id
|
106
|
+
|
107
|
+
nykredit = apple.create_account({ :credit_limit => 30}, false)
|
108
|
+
assert_equal apple.id, nykredit.firm_id
|
109
|
+
assert_equal apple.id, citibank.firm_id
|
110
|
+
assert_equal apple.id, hsbc.firm_id
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_assignment_without_replacement_on_create
|
114
|
+
apple = Firm.create("name" => "Apple")
|
115
|
+
citibank = Account.create("credit_limit" => 10)
|
116
|
+
apple.account = citibank
|
117
|
+
assert_equal apple.id, citibank.firm_id
|
118
|
+
|
119
|
+
hsbc = apple.create_account({:credit_limit => 10}, false)
|
120
|
+
assert_equal apple.id, hsbc.firm_id
|
121
|
+
hsbc.save
|
122
|
+
assert_equal apple.id, citibank.firm_id
|
123
|
+
end
|
100
124
|
|
101
125
|
def test_dependence
|
102
126
|
firm = Firm.find(1)
|
103
127
|
assert !firm.account.nil?
|
104
128
|
firm.destroy
|
105
|
-
assert_equal 1, Account.
|
129
|
+
assert_equal 1, Account.count
|
106
130
|
end
|
107
131
|
|
108
132
|
def test_succesful_build_association
|
@@ -227,56 +251,53 @@ end
|
|
227
251
|
|
228
252
|
|
229
253
|
class HasManyAssociationsTest < Test::Unit::TestCase
|
230
|
-
fixtures :accounts, :companies, :developers, :projects,
|
231
|
-
|
232
|
-
def setup
|
233
|
-
@signals37 = Firm.find(1)
|
234
|
-
end
|
254
|
+
fixtures :accounts, :companies, :developers, :projects,
|
255
|
+
:developers_projects, :topics
|
235
256
|
|
236
257
|
def force_signal37_to_load_all_clients_of_firm
|
237
|
-
|
258
|
+
companies(:first_firm).clients_of_firm.each {|f| }
|
238
259
|
end
|
239
260
|
|
240
261
|
def test_counting
|
241
|
-
assert_equal 2, Firm.
|
262
|
+
assert_equal 2, Firm.find(:first).clients.count
|
242
263
|
end
|
243
264
|
|
244
265
|
def test_finding
|
245
|
-
assert_equal 2, Firm.
|
266
|
+
assert_equal 2, Firm.find(:first).clients.length
|
246
267
|
end
|
247
268
|
|
248
269
|
def test_finding_default_orders
|
249
|
-
assert_equal "Summit", Firm.
|
270
|
+
assert_equal "Summit", Firm.find(:first).clients.first.name
|
250
271
|
end
|
251
272
|
|
252
273
|
def test_finding_with_different_class_name_and_order
|
253
|
-
assert_equal "Microsoft", Firm.
|
274
|
+
assert_equal "Microsoft", Firm.find(:first).clients_sorted_desc.first.name
|
254
275
|
end
|
255
276
|
|
256
277
|
def test_finding_with_foreign_key
|
257
|
-
assert_equal "Microsoft", Firm.
|
278
|
+
assert_equal "Microsoft", Firm.find(:first).clients_of_firm.first.name
|
258
279
|
end
|
259
280
|
|
260
281
|
def test_finding_with_condition
|
261
|
-
assert_equal "Microsoft", Firm.
|
282
|
+
assert_equal "Microsoft", Firm.find(:first).clients_like_ms.first.name
|
262
283
|
end
|
263
284
|
|
264
285
|
def test_finding_using_sql
|
265
|
-
firm = Firm.
|
286
|
+
firm = Firm.find(:first)
|
266
287
|
first_client = firm.clients_using_sql.first
|
267
288
|
assert_not_nil first_client
|
268
289
|
assert_equal "Microsoft", first_client.name
|
269
290
|
assert_equal 1, firm.clients_using_sql.size
|
270
|
-
assert_equal 1, Firm.
|
291
|
+
assert_equal 1, Firm.find(:first).clients_using_sql.size
|
271
292
|
end
|
272
293
|
|
273
294
|
def test_counting_using_sql
|
274
|
-
assert_equal 1, Firm.
|
275
|
-
assert_equal 0, Firm.
|
295
|
+
assert_equal 1, Firm.find(:first).clients_using_counter_sql.size
|
296
|
+
assert_equal 0, Firm.find(:first).clients_using_zero_counter_sql.size
|
276
297
|
end
|
277
298
|
|
278
299
|
def test_counting_non_existant_items_using_sql
|
279
|
-
assert_equal 0, Firm.
|
300
|
+
assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size
|
280
301
|
end
|
281
302
|
|
282
303
|
def test_belongs_to_sanity
|
@@ -295,7 +316,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
295
316
|
end
|
296
317
|
|
297
318
|
def test_find_ids
|
298
|
-
firm = Firm.
|
319
|
+
firm = Firm.find(:first)
|
299
320
|
|
300
321
|
assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find }
|
301
322
|
|
@@ -324,43 +345,52 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
324
345
|
def test_find_all_sanitized
|
325
346
|
firm = Firm.find_first
|
326
347
|
assert_equal firm.clients.find_all("name = 'Summit'"), firm.clients.find_all(["name = '%s'", "Summit"])
|
348
|
+
summit = firm.clients.find(:all, :conditions => "name = 'Summit'")
|
349
|
+
assert_equal summit, firm.clients.find(:all, :conditions => ["name = ?", "Summit"])
|
350
|
+
assert_equal summit, firm.clients.find(:all, :conditions => ["name = :name", { :name => "Summit" }])
|
327
351
|
end
|
328
352
|
|
329
353
|
def test_find_first
|
330
354
|
firm = Firm.find_first
|
355
|
+
client2 = Client.find(2)
|
331
356
|
assert_equal firm.clients.first, firm.clients.find_first
|
332
|
-
assert_equal
|
357
|
+
assert_equal client2, firm.clients.find_first("type = 'Client'")
|
358
|
+
assert_equal client2, firm.clients.find(:first, :conditions => "type = 'Client'")
|
333
359
|
end
|
334
360
|
|
335
361
|
def test_find_first_sanitized
|
336
|
-
|
362
|
+
firm = Firm.find_first
|
363
|
+
client2 = Client.find(2)
|
364
|
+
assert_equal client2, firm.clients.find_first(["type = ?", "Client"])
|
365
|
+
assert_equal client2, firm.clients.find(:first, :conditions => ['type = ?', 'Client'])
|
366
|
+
assert_equal client2, firm.clients.find(:first, :conditions => ['type = :type', { :type => 'Client' }])
|
337
367
|
end
|
338
368
|
|
339
369
|
def test_find_in_collection
|
340
|
-
assert_equal Client.find(2).name,
|
341
|
-
assert_raises(ActiveRecord::RecordNotFound) {
|
370
|
+
assert_equal Client.find(2).name, companies(:first_firm).clients.find(2).name
|
371
|
+
assert_raises(ActiveRecord::RecordNotFound) { companies(:first_firm).clients.find(6) }
|
342
372
|
end
|
343
373
|
|
344
374
|
def test_adding
|
345
375
|
force_signal37_to_load_all_clients_of_firm
|
346
376
|
natural = Client.new("name" => "Natural Company")
|
347
|
-
|
348
|
-
assert_equal 2,
|
349
|
-
assert_equal 2,
|
350
|
-
assert_equal natural,
|
377
|
+
companies(:first_firm).clients_of_firm << natural
|
378
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size # checking via the collection
|
379
|
+
assert_equal 2, companies(:first_firm).clients_of_firm(true).size # checking using the db
|
380
|
+
assert_equal natural, companies(:first_firm).clients_of_firm.last
|
351
381
|
end
|
352
382
|
|
353
383
|
def test_adding_a_mismatch_class
|
354
|
-
assert_raises(ActiveRecord::AssociationTypeMismatch) {
|
355
|
-
assert_raises(ActiveRecord::AssociationTypeMismatch) {
|
356
|
-
assert_raises(ActiveRecord::AssociationTypeMismatch) {
|
384
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil }
|
385
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 }
|
386
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << Topic.find(1) }
|
357
387
|
end
|
358
388
|
|
359
389
|
def test_adding_a_collection
|
360
390
|
force_signal37_to_load_all_clients_of_firm
|
361
|
-
|
362
|
-
assert_equal 3,
|
363
|
-
assert_equal 3,
|
391
|
+
companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
|
392
|
+
assert_equal 3, companies(:first_firm).clients_of_firm.size
|
393
|
+
assert_equal 3, companies(:first_firm).clients_of_firm(true).size
|
364
394
|
end
|
365
395
|
|
366
396
|
def test_adding_before_save
|
@@ -406,51 +436,51 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
406
436
|
end
|
407
437
|
|
408
438
|
def test_build
|
409
|
-
new_client =
|
439
|
+
new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client")
|
410
440
|
assert_equal "Another Client", new_client.name
|
411
441
|
assert new_client.new_record?
|
412
|
-
assert_equal new_client,
|
413
|
-
assert
|
442
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm.last
|
443
|
+
assert companies(:first_firm).save
|
414
444
|
assert !new_client.new_record?
|
415
|
-
assert_equal 2,
|
445
|
+
assert_equal 2, companies(:first_firm).clients_of_firm(true).size
|
416
446
|
end
|
417
447
|
|
418
448
|
def test_build_many
|
419
|
-
new_clients =
|
449
|
+
new_clients = companies(:first_firm).clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}])
|
420
450
|
assert_equal 2, new_clients.size
|
421
451
|
|
422
|
-
assert
|
423
|
-
assert_equal 3,
|
452
|
+
assert companies(:first_firm).save
|
453
|
+
assert_equal 3, companies(:first_firm).clients_of_firm(true).size
|
424
454
|
end
|
425
455
|
|
426
456
|
def test_invalid_build
|
427
|
-
new_client =
|
457
|
+
new_client = companies(:first_firm).clients_of_firm.build
|
428
458
|
assert new_client.new_record?
|
429
459
|
assert !new_client.valid?
|
430
|
-
assert_equal new_client,
|
431
|
-
assert
|
460
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm.last
|
461
|
+
assert !companies(:first_firm).save
|
432
462
|
assert new_client.new_record?
|
433
|
-
assert_equal 1,
|
463
|
+
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
|
434
464
|
end
|
435
465
|
|
436
466
|
def test_create
|
437
467
|
force_signal37_to_load_all_clients_of_firm
|
438
|
-
new_client =
|
468
|
+
new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
439
469
|
assert !new_client.new_record?
|
440
|
-
assert_equal new_client,
|
441
|
-
assert_equal new_client,
|
470
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm.last
|
471
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
|
442
472
|
end
|
443
473
|
|
444
474
|
def test_create_many
|
445
|
-
|
446
|
-
assert_equal 3,
|
475
|
+
companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
|
476
|
+
assert_equal 3, companies(:first_firm).clients_of_firm(true).size
|
447
477
|
end
|
448
478
|
|
449
479
|
def test_deleting
|
450
480
|
force_signal37_to_load_all_clients_of_firm
|
451
|
-
|
452
|
-
assert_equal 0,
|
453
|
-
assert_equal 0,
|
481
|
+
companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first)
|
482
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
483
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
454
484
|
end
|
455
485
|
|
456
486
|
def test_deleting_before_save
|
@@ -463,29 +493,29 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
463
493
|
|
464
494
|
def test_deleting_a_collection
|
465
495
|
force_signal37_to_load_all_clients_of_firm
|
466
|
-
|
467
|
-
assert_equal 2,
|
468
|
-
|
469
|
-
|
470
|
-
assert_equal 0,
|
471
|
-
assert_equal 0,
|
496
|
+
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
497
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size
|
498
|
+
#companies(:first_firm).clients_of_firm.clear
|
499
|
+
companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]])
|
500
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
501
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
472
502
|
end
|
473
503
|
|
474
504
|
def test_deleting_a_association_collection
|
475
505
|
force_signal37_to_load_all_clients_of_firm
|
476
|
-
|
477
|
-
assert_equal 2,
|
478
|
-
|
479
|
-
assert_equal 0,
|
480
|
-
assert_equal 0,
|
506
|
+
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
507
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size
|
508
|
+
companies(:first_firm).clients_of_firm.clear
|
509
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
510
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
481
511
|
end
|
482
512
|
|
483
513
|
def test_deleting_a_item_which_is_not_in_the_collection
|
484
514
|
force_signal37_to_load_all_clients_of_firm
|
485
515
|
summit = Client.find_first("name = 'Summit'")
|
486
|
-
|
487
|
-
assert_equal 1,
|
488
|
-
assert_equal 1,
|
516
|
+
companies(:first_firm).clients_of_firm.delete(summit)
|
517
|
+
assert_equal 1, companies(:first_firm).clients_of_firm.size
|
518
|
+
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
|
489
519
|
assert_equal 2, summit.client_of
|
490
520
|
end
|
491
521
|
|
@@ -503,20 +533,21 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
503
533
|
|
504
534
|
def test_destroy_all
|
505
535
|
force_signal37_to_load_all_clients_of_firm
|
506
|
-
assert
|
507
|
-
|
508
|
-
assert
|
509
|
-
assert
|
536
|
+
assert !companies(:first_firm).clients_of_firm.empty?, "37signals has clients after load"
|
537
|
+
companies(:first_firm).clients_of_firm.destroy_all
|
538
|
+
assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all"
|
539
|
+
assert companies(:first_firm).clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh"
|
510
540
|
end
|
511
541
|
|
512
542
|
def test_dependence
|
513
|
-
|
514
|
-
|
515
|
-
|
543
|
+
firm = companies(:first_firm)
|
544
|
+
assert_equal 2, firm.clients.size
|
545
|
+
firm.destroy
|
546
|
+
assert Client.find(:all, :conditions => "firm_id=#{firm.id}").empty?
|
516
547
|
end
|
517
548
|
|
518
549
|
def test_destroy_dependent_when_deleted_from_association
|
519
|
-
firm = Firm.
|
550
|
+
firm = Firm.find(:first)
|
520
551
|
assert_equal 2, firm.clients.size
|
521
552
|
|
522
553
|
client = firm.clients.first
|
@@ -535,43 +566,81 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
535
566
|
assert_nothing_raised { topic.destroy }
|
536
567
|
end
|
537
568
|
|
569
|
+
uses_transaction :test_dependence_with_transaction_support_on_failure
|
538
570
|
def test_dependence_with_transaction_support_on_failure
|
539
|
-
|
540
|
-
firm = Firm.find_first
|
571
|
+
firm = companies(:first_firm)
|
541
572
|
clients = firm.clients
|
573
|
+
assert_equal 2, clients.length
|
542
574
|
clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end }
|
543
575
|
|
544
576
|
firm.destroy rescue "do nothing"
|
545
577
|
|
546
|
-
assert_equal 2, Client.
|
578
|
+
assert_equal 2, Client.find(:all, :conditions => "firm_id=#{firm.id}").size
|
547
579
|
end
|
548
580
|
|
549
581
|
def test_dependence_on_account
|
550
|
-
assert_equal 2, Account.
|
551
|
-
|
552
|
-
assert_equal 1, Account.
|
582
|
+
assert_equal 2, Account.count
|
583
|
+
companies(:first_firm).destroy
|
584
|
+
assert_equal 1, Account.count
|
553
585
|
end
|
554
586
|
|
555
587
|
def test_included_in_collection
|
556
|
-
assert
|
588
|
+
assert companies(:first_firm).clients.include?(Client.find(2))
|
557
589
|
end
|
558
590
|
|
559
591
|
def test_adding_array_and_collection
|
560
|
-
assert_nothing_raised { Firm.
|
592
|
+
assert_nothing_raised { Firm.find(:first).clients + Firm.find(:all).last.clients }
|
561
593
|
end
|
562
|
-
end
|
563
594
|
|
564
|
-
|
565
|
-
|
595
|
+
def test_find_all_without_conditions
|
596
|
+
firm = companies(:first_firm)
|
597
|
+
assert_equal 2, firm.clients.find(:all).length
|
598
|
+
end
|
599
|
+
|
600
|
+
def test_replace_with_less
|
601
|
+
firm = Firm.find(:first)
|
602
|
+
firm.clients = [companies(:first_client)]
|
603
|
+
assert firm.save, "Could not save firm"
|
604
|
+
firm.reload
|
605
|
+
assert_equal 1, firm.clients.length
|
606
|
+
end
|
607
|
+
|
608
|
+
def test_replace_with_new
|
609
|
+
firm = Firm.find(:first)
|
610
|
+
new_client = Client.new("name" => "New Client")
|
611
|
+
firm.clients = [companies(:second_client),new_client]
|
612
|
+
firm.save
|
613
|
+
firm.reload
|
614
|
+
assert_equal 2, firm.clients.length
|
615
|
+
assert !firm.clients.include?(:first_client)
|
616
|
+
end
|
566
617
|
|
567
|
-
def
|
568
|
-
|
569
|
-
|
618
|
+
def test_replace_on_new_object
|
619
|
+
firm = Firm.new("name" => "New Firm")
|
620
|
+
firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
|
621
|
+
assert firm.save
|
622
|
+
firm.reload
|
623
|
+
assert_equal 2, firm.clients.length
|
624
|
+
assert firm.clients.include?(Client.find_by_name("New Client"))
|
570
625
|
end
|
626
|
+
|
627
|
+
def test_assign_ids
|
628
|
+
firm = Firm.new("name" => "Apple")
|
629
|
+
firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
|
630
|
+
firm.save
|
631
|
+
firm.reload
|
632
|
+
assert_equal 2, firm.clients.length
|
633
|
+
assert firm.clients.include?(companies(:second_client))
|
634
|
+
end
|
635
|
+
end
|
571
636
|
|
637
|
+
class BelongsToAssociationsTest < Test::Unit::TestCase
|
638
|
+
fixtures :accounts, :companies, :developers, :projects, :topics,
|
639
|
+
:developers_projects
|
640
|
+
|
572
641
|
def test_belongs_to
|
573
642
|
Client.find(3).firm.name
|
574
|
-
assert_equal
|
643
|
+
assert_equal companies(:first_firm).name, Client.find(3).firm.name
|
575
644
|
assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
|
576
645
|
end
|
577
646
|
|
@@ -630,7 +699,7 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
|
|
630
699
|
end
|
631
700
|
|
632
701
|
def test_assignment_before_parent_saved
|
633
|
-
client = Client.
|
702
|
+
client = Client.find(:first)
|
634
703
|
apple = Firm.new("name" => "Apple")
|
635
704
|
client.firm = apple
|
636
705
|
assert_equal apple, client.firm
|
@@ -669,7 +738,7 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
|
|
669
738
|
|
670
739
|
def test_new_record_with_foreign_key_but_no_object
|
671
740
|
c = Client.new("firm_id" => 1)
|
672
|
-
assert_equal Firm.
|
741
|
+
assert_equal Firm.find(:first), c.firm_with_basic_id
|
673
742
|
end
|
674
743
|
|
675
744
|
def test_forgetting_the_load_when_foreign_key_enters_late
|
@@ -677,7 +746,7 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
|
|
677
746
|
assert_nil c.firm_with_basic_id
|
678
747
|
|
679
748
|
c.firm_id = 1
|
680
|
-
assert_equal Firm.
|
749
|
+
assert_equal Firm.find(:first), c.firm_with_basic_id
|
681
750
|
end
|
682
751
|
|
683
752
|
def test_field_name_same_as_foreign_key
|
@@ -695,12 +764,39 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
|
|
695
764
|
apple.companies_count = 2
|
696
765
|
apple.save
|
697
766
|
|
698
|
-
apple = Firm.
|
767
|
+
apple = Firm.find(:first, :conditions => "name = 'Apple'")
|
699
768
|
assert_equal 2, apple.clients.size, "Should use the new cached number"
|
700
769
|
|
701
770
|
apple.clients.to_s
|
702
771
|
assert_equal 1, apple.clients.size, "Should not use the cached number, but go to the database"
|
703
772
|
end
|
773
|
+
|
774
|
+
end
|
775
|
+
|
776
|
+
|
777
|
+
class ProjectWithAfterCreateHook < ActiveRecord::Base
|
778
|
+
set_table_name 'projects'
|
779
|
+
has_and_belongs_to_many :developers,
|
780
|
+
:class_name => "DeveloperForProjectWithAfterCreateHook",
|
781
|
+
:join_table => "developers_projects",
|
782
|
+
:foreign_key => "project_id",
|
783
|
+
:association_foreign_key => "developer_id"
|
784
|
+
|
785
|
+
after_create :add_david
|
786
|
+
|
787
|
+
def add_david
|
788
|
+
david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
|
789
|
+
david.projects << self
|
790
|
+
end
|
791
|
+
end
|
792
|
+
|
793
|
+
class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
|
794
|
+
set_table_name 'developers'
|
795
|
+
has_and_belongs_to_many :projects,
|
796
|
+
:class_name => "ProjectWithAfterCreateHook",
|
797
|
+
:join_table => "developers_projects",
|
798
|
+
:association_foreign_key => "project_id",
|
799
|
+
:foreign_key => "developer_id"
|
704
800
|
end
|
705
801
|
|
706
802
|
|
@@ -716,9 +812,9 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
716
812
|
active_record = Project.find(1)
|
717
813
|
assert !active_record.developers.empty?
|
718
814
|
assert_equal 2, active_record.developers.size
|
719
|
-
|
815
|
+
assert active_record.developers.include?(david)
|
720
816
|
end
|
721
|
-
|
817
|
+
|
722
818
|
def test_adding_single
|
723
819
|
jamis = Developer.find(2)
|
724
820
|
jamis.projects.reload # causing the collection to load
|
@@ -753,8 +849,24 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
753
849
|
assert_equal 2, action_controller.developers(true).size
|
754
850
|
end
|
755
851
|
|
852
|
+
def test_adding_from_the_project_fixed_timestamp
|
853
|
+
jamis = Developer.find(2)
|
854
|
+
action_controller = Project.find(2)
|
855
|
+
action_controller.developers.reload
|
856
|
+
assert_equal 1, jamis.projects.size
|
857
|
+
assert_equal 1, action_controller.developers.size
|
858
|
+
updated_at = jamis.updated_at
|
859
|
+
|
860
|
+
action_controller.developers << jamis
|
861
|
+
|
862
|
+
assert_equal updated_at, jamis.updated_at
|
863
|
+
assert_equal 2, jamis.projects(true).size
|
864
|
+
assert_equal 2, action_controller.developers.size
|
865
|
+
assert_equal 2, action_controller.developers(true).size
|
866
|
+
end
|
867
|
+
|
756
868
|
def test_adding_multiple
|
757
|
-
aredridel = Developer.new("name" => "
|
869
|
+
aredridel = Developer.new("name" => "Aredridel")
|
758
870
|
aredridel.save
|
759
871
|
aredridel.projects.reload
|
760
872
|
aredridel.projects.push(Project.find(1), Project.find(2))
|
@@ -763,7 +875,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
763
875
|
end
|
764
876
|
|
765
877
|
def test_adding_a_collection
|
766
|
-
aredridel = Developer.new("name" => "
|
878
|
+
aredridel = Developer.new("name" => "Aredridel")
|
767
879
|
aredridel.save
|
768
880
|
aredridel.projects.reload
|
769
881
|
aredridel.projects.concat([Project.find(1), Project.find(2)])
|
@@ -774,7 +886,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
774
886
|
def test_habtm_adding_before_save
|
775
887
|
no_of_devels = Developer.count
|
776
888
|
no_of_projects = Project.count
|
777
|
-
aredridel = Developer.new("name" => "
|
889
|
+
aredridel = Developer.new("name" => "Aredridel")
|
778
890
|
aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
|
779
891
|
assert aredridel.new_record?
|
780
892
|
assert p.new_record?
|
@@ -790,6 +902,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
790
902
|
no_of_devels = Developer.count
|
791
903
|
no_of_projects = Project.count
|
792
904
|
now = Date.today
|
905
|
+
sqlnow = Time.now.strftime("%Y/%m/%d 00:00:00")
|
793
906
|
ken = Developer.new("name" => "Ken")
|
794
907
|
ken.projects.push_with_attributes( Project.find(1), :joined_on => now )
|
795
908
|
p = Project.new("name" => "Foomatic")
|
@@ -804,7 +917,13 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
804
917
|
assert_equal 2, ken.projects(true).size
|
805
918
|
|
806
919
|
kenReloaded = Developer.find_by_name 'Ken'
|
807
|
-
|
920
|
+
# SQL Server doesn't have a separate column type just for dates,
|
921
|
+
# so the time is in the string and incorrectly formatted
|
922
|
+
if ActiveRecord::ConnectionAdapters.const_defined? :SQLServerAdapter and ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::SQLServerAdapter)
|
923
|
+
kenReloaded.projects.each { |prj| assert_equal(sqlnow, prj.joined_on.to_s) }
|
924
|
+
else
|
925
|
+
kenReloaded.projects.each { |prj| assert_equal(now.to_s, prj.joined_on.to_s) }
|
926
|
+
end
|
808
927
|
end
|
809
928
|
|
810
929
|
def test_build
|
@@ -825,16 +944,16 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
825
944
|
end
|
826
945
|
|
827
946
|
def test_uniq_after_the_fact
|
828
|
-
|
829
|
-
|
830
|
-
assert_equal 3,
|
831
|
-
assert_equal 1,
|
947
|
+
developers(:jamis).projects << projects(:active_record)
|
948
|
+
developers(:jamis).projects << projects(:active_record)
|
949
|
+
assert_equal 3, developers(:jamis).projects.size
|
950
|
+
assert_equal 1, developers(:jamis).projects.uniq.size
|
832
951
|
end
|
833
952
|
|
834
953
|
def test_uniq_before_the_fact
|
835
|
-
|
836
|
-
|
837
|
-
assert_equal 2,
|
954
|
+
projects(:active_record).developers << developers(:jamis)
|
955
|
+
projects(:active_record).developers << developers(:david)
|
956
|
+
assert_equal 2, projects(:active_record, :reload).developers.size
|
838
957
|
end
|
839
958
|
|
840
959
|
def test_deleting
|
@@ -854,11 +973,30 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
854
973
|
def test_deleting_array
|
855
974
|
david = Developer.find(1)
|
856
975
|
david.projects.reload
|
857
|
-
david.projects.delete(Project.
|
976
|
+
david.projects.delete(Project.find(:all))
|
858
977
|
assert_equal 0, david.projects.size
|
859
978
|
assert_equal 0, david.projects(true).size
|
860
979
|
end
|
861
980
|
|
981
|
+
def test_deleting_with_sql
|
982
|
+
david = Developer.find(1)
|
983
|
+
active_record = Project.find(1)
|
984
|
+
active_record.developers.reload
|
985
|
+
assert_equal 2, active_record.developers_by_sql.size
|
986
|
+
|
987
|
+
active_record.developers_by_sql.delete(david)
|
988
|
+
assert_equal 1, active_record.developers_by_sql(true).size
|
989
|
+
end
|
990
|
+
|
991
|
+
def test_deleting_array_with_sql
|
992
|
+
active_record = Project.find(1)
|
993
|
+
active_record.developers.reload
|
994
|
+
assert_equal 2, active_record.developers_by_sql.size
|
995
|
+
|
996
|
+
active_record.developers_by_sql.delete(Developer.find(:all))
|
997
|
+
assert_equal 0, active_record.developers_by_sql(true).size
|
998
|
+
end
|
999
|
+
|
862
1000
|
def test_deleting_all
|
863
1001
|
david = Developer.find(1)
|
864
1002
|
david.projects.reload
|
@@ -873,7 +1011,13 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
873
1011
|
end
|
874
1012
|
|
875
1013
|
def test_additional_columns_from_join_table
|
876
|
-
|
1014
|
+
# SQL Server doesn't have a separate column type just for dates,
|
1015
|
+
# so the time is in the string and incorrectly formatted
|
1016
|
+
if ActiveRecord::ConnectionAdapters.const_defined? :SQLServerAdapter and ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::SQLServerAdapter)
|
1017
|
+
assert_equal Time.mktime(2004, 10, 10).strftime("%Y/%m/%d 00:00:00"), Developer.find(1).projects.first.joined_on.to_s
|
1018
|
+
else
|
1019
|
+
assert_equal Date.new(2004, 10, 10).to_s, Developer.find(1).projects.first.joined_on.to_s
|
1020
|
+
end
|
877
1021
|
end
|
878
1022
|
|
879
1023
|
def test_destroy_all
|
@@ -886,35 +1030,93 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
886
1030
|
end
|
887
1031
|
|
888
1032
|
def test_rich_association
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
1033
|
+
jamis = developers(:jamis)
|
1034
|
+
jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today)
|
1035
|
+
# SQL Server doesn't have a separate column type just for dates,
|
1036
|
+
# so the time is in the string and incorrectly formatted
|
1037
|
+
if ActiveRecord::ConnectionAdapters.const_defined? :SQLServerAdapter and ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::SQLServerAdapter)
|
1038
|
+
assert_equal Time.now.strftime("%Y/%m/%d 00:00:00"), jamis.projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.to_s
|
1039
|
+
assert_equal Time.now.strftime("%Y/%m/%d 00:00:00"), developers(:jamis).projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.to_s
|
1040
|
+
else
|
1041
|
+
assert_equal Date.today.to_s, jamis.projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.to_s
|
1042
|
+
assert_equal Date.today.to_s, developers(:jamis).projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.to_s
|
1043
|
+
end
|
893
1044
|
end
|
894
1045
|
|
895
1046
|
def test_associations_with_conditions
|
896
|
-
assert_equal 2,
|
897
|
-
assert_equal 1,
|
898
|
-
|
899
|
-
|
900
|
-
assert_equal
|
1047
|
+
assert_equal 2, projects(:active_record).developers.size
|
1048
|
+
assert_equal 1, projects(:active_record).developers_named_david.size
|
1049
|
+
|
1050
|
+
assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id)
|
1051
|
+
assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id)
|
1052
|
+
|
1053
|
+
projects(:active_record).developers_named_david.clear
|
1054
|
+
assert_equal 1, projects(:active_record, :reload).developers.size
|
901
1055
|
end
|
902
1056
|
|
903
1057
|
def test_find_in_association
|
904
1058
|
# Using sql
|
905
|
-
assert_equal
|
1059
|
+
assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find"
|
906
1060
|
|
907
1061
|
# Using ruby
|
908
|
-
|
909
|
-
|
910
|
-
assert_equal
|
1062
|
+
active_record = projects(:active_record)
|
1063
|
+
active_record.developers.reload
|
1064
|
+
assert_equal developers(:david), active_record.developers.find(developers(:david).id), "Ruby find"
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
def test_new_with_values_in_collection
|
1068
|
+
jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis')
|
1069
|
+
david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
|
1070
|
+
project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie")
|
1071
|
+
project.developers << jamis
|
1072
|
+
project.save!
|
1073
|
+
project.reload
|
1074
|
+
|
1075
|
+
assert project.developers.include?(jamis)
|
1076
|
+
assert project.developers.include?(david)
|
911
1077
|
end
|
912
1078
|
|
913
1079
|
def xtest_find_in_association_with_options
|
914
|
-
developers =
|
1080
|
+
developers = projects(:active_record).developers.find(:all)
|
915
1081
|
assert_equal 2, developers.size
|
916
1082
|
|
917
|
-
assert_equal
|
918
|
-
assert_equal
|
1083
|
+
assert_equal developers(:david), projects(:active_record).developers.find(:first, :conditions => "salary < 10000")
|
1084
|
+
assert_equal developers(:jamis), projects(:active_record).developers.find(:first, :order => "salary DESC")
|
919
1085
|
end
|
920
|
-
|
1086
|
+
|
1087
|
+
def test_replace_with_less
|
1088
|
+
david = developers(:david)
|
1089
|
+
david.projects = [projects(:action_controller)]
|
1090
|
+
assert david.save
|
1091
|
+
assert_equal 1, david.projects.length
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
def test_replace_with_new
|
1095
|
+
david = developers(:david)
|
1096
|
+
david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
|
1097
|
+
david.save
|
1098
|
+
assert_equal 2, david.projects.length
|
1099
|
+
assert !david.projects.include?(projects(:active_record))
|
1100
|
+
end
|
1101
|
+
|
1102
|
+
def test_replace_on_new_object
|
1103
|
+
new_developer = Developer.new("name" => "Matz")
|
1104
|
+
new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
|
1105
|
+
new_developer.save
|
1106
|
+
assert_equal 2, new_developer.projects.length
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
def test_consider_type
|
1110
|
+
developer = Developer.find(:first)
|
1111
|
+
special_project = SpecialProject.create("name" => "Special Project")
|
1112
|
+
|
1113
|
+
other_project = developer.projects.first
|
1114
|
+
developer.special_projects << special_project
|
1115
|
+
developer.reload
|
1116
|
+
|
1117
|
+
assert developer.projects.include?(special_project)
|
1118
|
+
assert developer.special_projects.include?(special_project)
|
1119
|
+
assert !developer.special_projects.include?(other_project)
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
end
|