activerecord 1.0.0 → 1.1.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 +102 -1
- data/dev-utils/eval_debugger.rb +12 -7
- data/lib/active_record.rb +2 -0
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/associations.rb +74 -53
- data/lib/active_record/associations.rb.orig +555 -0
- data/lib/active_record/associations/association_collection.rb +74 -15
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +86 -25
- data/lib/active_record/associations/has_many_association.rb +48 -50
- data/lib/active_record/base.rb +56 -24
- data/lib/active_record/connection_adapters/abstract_adapter.rb +46 -3
- data/lib/active_record/connection_adapters/mysql_adapter.rb +15 -15
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +128 -135
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +76 -78
- data/lib/active_record/deprecated_associations.rb +1 -1
- data/lib/active_record/fixtures.rb +137 -54
- data/lib/active_record/observer.rb +1 -1
- data/lib/active_record/support/inflector.rb +8 -0
- data/lib/active_record/transactions.rb +31 -14
- data/rakefile +13 -5
- data/test/abstract_unit.rb +7 -1
- data/test/associations_test.rb +99 -27
- data/test/base_test.rb +15 -1
- data/test/connections/native_sqlite/connection.rb +24 -14
- data/test/deprecated_associations_test.rb +3 -4
- data/test/deprecated_associations_test.rb.orig +334 -0
- data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +1 -0
- data/test/fixtures/bad_fixtures/attr_with_spaces +1 -0
- data/test/fixtures/bad_fixtures/blank_line +3 -0
- data/test/fixtures/bad_fixtures/duplicate_attributes +3 -0
- data/test/fixtures/bad_fixtures/missing_value +1 -0
- data/test/fixtures/company_in_module.rb +15 -1
- data/test/fixtures/db_definitions/mysql.sql +2 -1
- data/test/fixtures/db_definitions/postgresql.sql +2 -1
- data/test/fixtures/db_definitions/sqlite.sql +2 -1
- data/test/fixtures/developers_projects/david_action_controller +2 -1
- data/test/fixtures/developers_projects/david_active_record +2 -1
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/project.rb +2 -1
- data/test/fixtures/projects/action_controller +1 -1
- data/test/fixtures/topics/second +1 -1
- data/test/fixtures_test.rb +63 -4
- data/test/inflector_test.rb +17 -0
- data/test/modules_test.rb +8 -0
- data/test/transactions_test.rb +16 -4
- metadata +10 -2
data/test/associations_test.rb
CHANGED
@@ -42,7 +42,8 @@ class AssociationsTest < Test::Unit::TestCase
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_storing_in_pstore
|
45
|
-
|
45
|
+
require "tmpdir"
|
46
|
+
store_filename = File.join(Dir.tmpdir, "ar-pstore-association-test")
|
46
47
|
File.delete(store_filename) if File.exists?(store_filename)
|
47
48
|
require "pstore"
|
48
49
|
apple = Firm.create("name" => "Apple")
|
@@ -170,8 +171,9 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
170
171
|
|
171
172
|
def test_finding_using_sql
|
172
173
|
firm = Firm.find_first
|
173
|
-
firm.clients_using_sql.first
|
174
|
-
|
174
|
+
first_client = firm.clients_using_sql.first
|
175
|
+
assert_not_nil first_client
|
176
|
+
assert_equal "Microsoft", first_client.name
|
175
177
|
assert_equal 1, firm.clients_using_sql.size
|
176
178
|
assert_equal 1, Firm.find_first.clients_using_sql.size
|
177
179
|
end
|
@@ -181,6 +183,11 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
181
183
|
assert_equal 1, Firm.find_first.clients.find_all("name = 'Summit'").length
|
182
184
|
end
|
183
185
|
|
186
|
+
def test_find_all_sanitized
|
187
|
+
firm = Firm.find_first
|
188
|
+
assert_equal firm.clients.find_all("name = 'Summit'"), firm.clients.find_all(["name = '%s'", "Summit"])
|
189
|
+
end
|
190
|
+
|
184
191
|
def test_find_in_collection
|
185
192
|
assert_equal Client.find(2).name, @signals37.clients.find(2).name
|
186
193
|
assert_equal Client.find(2).name, @signals37.clients.find {|c| c.name == @signals37.clients.find(2).name }.name
|
@@ -204,7 +211,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
204
211
|
|
205
212
|
def test_adding_a_collection
|
206
213
|
force_signal37_to_load_all_clients_of_firm
|
207
|
-
@signals37.clients_of_firm.concat(Client.new("name" => "Natural Company"), Client.new("name" => "Apple"))
|
214
|
+
@signals37.clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
|
208
215
|
assert_equal 3, @signals37.clients_of_firm.size
|
209
216
|
assert_equal 3, @signals37.clients_of_firm(true).size
|
210
217
|
end
|
@@ -234,6 +241,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
234
241
|
force_signal37_to_load_all_clients_of_firm
|
235
242
|
@signals37.clients_of_firm.create("name" => "Another Client")
|
236
243
|
assert_equal 2, @signals37.clients_of_firm.size
|
244
|
+
#@signals37.clients_of_firm.clear
|
237
245
|
@signals37.clients_of_firm.delete([@signals37.clients_of_firm[0], @signals37.clients_of_firm[1]])
|
238
246
|
assert_equal 0, @signals37.clients_of_firm.size
|
239
247
|
assert_equal 0, @signals37.clients_of_firm(true).size
|
@@ -243,7 +251,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
243
251
|
force_signal37_to_load_all_clients_of_firm
|
244
252
|
@signals37.clients_of_firm.create("name" => "Another Client")
|
245
253
|
assert_equal 2, @signals37.clients_of_firm.size
|
246
|
-
@signals37.clients_of_firm.
|
254
|
+
@signals37.clients_of_firm.clear
|
247
255
|
assert_equal 0, @signals37.clients_of_firm.size
|
248
256
|
assert_equal 0, @signals37.clients_of_firm(true).size
|
249
257
|
end
|
@@ -257,12 +265,24 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
257
265
|
assert_equal 2, summit.client_of
|
258
266
|
end
|
259
267
|
|
268
|
+
def test_deleting_type_mismatch
|
269
|
+
david = Developer.find(1)
|
270
|
+
david.projects.id
|
271
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(1) }
|
272
|
+
end
|
273
|
+
|
274
|
+
def test_deleting_self_type_mismatch
|
275
|
+
david = Developer.find(1)
|
276
|
+
david.projects.id
|
277
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(Project.find(1).developers) }
|
278
|
+
end
|
279
|
+
|
260
280
|
def test_destroy_all
|
261
281
|
force_signal37_to_load_all_clients_of_firm
|
262
|
-
assert !@signals37.clients_of_firm.empty
|
282
|
+
assert !@signals37.clients_of_firm.empty?, "37signals has clients after load"
|
263
283
|
@signals37.clients_of_firm.destroy_all
|
264
|
-
assert @signals37.clients_of_firm.empty
|
265
|
-
assert @signals37.clients_of_firm(true).empty
|
284
|
+
assert @signals37.clients_of_firm.empty?, "37signals has no clients after destroy all"
|
285
|
+
assert @signals37.clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh"
|
266
286
|
end
|
267
287
|
|
268
288
|
def test_dependence
|
@@ -291,6 +311,10 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
291
311
|
def test_included_in_collection
|
292
312
|
assert @signals37.clients.include?(Client.find(2))
|
293
313
|
end
|
314
|
+
|
315
|
+
def test_adding_array_and_collection
|
316
|
+
assert_nothing_raised { Firm.find_first.clients + Firm.find_all.last.clients }
|
317
|
+
end
|
294
318
|
end
|
295
319
|
|
296
320
|
class BelongsToAssociationsTest < Test::Unit::TestCase
|
@@ -306,8 +330,8 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
|
|
306
330
|
end
|
307
331
|
|
308
332
|
def test_type_mismatch
|
309
|
-
|
310
|
-
|
333
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
|
334
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
|
311
335
|
end
|
312
336
|
|
313
337
|
def test_natural_assignment
|
@@ -327,12 +351,12 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
|
|
327
351
|
|
328
352
|
def test_with_different_class_name
|
329
353
|
assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
|
330
|
-
|
354
|
+
assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
|
331
355
|
end
|
332
356
|
|
333
357
|
def test_with_condition
|
334
358
|
assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
|
335
|
-
|
359
|
+
assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
|
336
360
|
end
|
337
361
|
|
338
362
|
def test_belongs_to_counter
|
@@ -367,12 +391,9 @@ end
|
|
367
391
|
|
368
392
|
class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
369
393
|
def setup
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
create_fixtures "developers"
|
374
|
-
create_fixtures "projects"
|
375
|
-
create_fixtures "developers_projects"
|
394
|
+
@accounts, @companies, @developers, @projects, @developers_projects =
|
395
|
+
create_fixtures "accounts", "companies", "developers", "projects", "developers_projects"
|
396
|
+
|
376
397
|
@signals37 = Firm.find(1)
|
377
398
|
end
|
378
399
|
|
@@ -388,7 +409,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
388
409
|
assert_equal david.name, active_record.developers.first.name
|
389
410
|
end
|
390
411
|
|
391
|
-
def
|
412
|
+
def test_adding_single
|
392
413
|
jamis = Developer.find(2)
|
393
414
|
jamis.projects.id # causing the collection to load
|
394
415
|
action_controller = Project.find(2)
|
@@ -404,8 +425,8 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
404
425
|
|
405
426
|
def test_adding_type_mismatch
|
406
427
|
jamis = Developer.find(2)
|
407
|
-
|
408
|
-
|
428
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil }
|
429
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 }
|
409
430
|
end
|
410
431
|
|
411
432
|
def test_adding_from_the_project
|
@@ -422,15 +443,37 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
422
443
|
assert_equal 2, action_controller.developers(true).size
|
423
444
|
end
|
424
445
|
|
446
|
+
def test_adding_multiple
|
447
|
+
aridridel = Developer.new("name" => "Aridridel")
|
448
|
+
aridridel.save
|
449
|
+
aridridel.projects.id
|
450
|
+
aridridel.projects.push(Project.find(1), Project.find(2))
|
451
|
+
assert_equal 2, aridridel.projects.size
|
452
|
+
assert_equal 2, aridridel.projects(true).size
|
453
|
+
end
|
454
|
+
|
425
455
|
def test_adding_a_collection
|
426
456
|
aridridel = Developer.new("name" => "Aridridel")
|
427
457
|
aridridel.save
|
428
458
|
aridridel.projects.id
|
429
|
-
aridridel.projects.concat([
|
459
|
+
aridridel.projects.concat([Project.find(1), Project.find(2)])
|
430
460
|
assert_equal 2, aridridel.projects.size
|
431
461
|
assert_equal 2, aridridel.projects(true).size
|
432
462
|
end
|
433
463
|
|
464
|
+
def test_uniq_after_the_fact
|
465
|
+
@developers["jamis"].find.projects << @projects["active_record"].find
|
466
|
+
@developers["jamis"].find.projects << @projects["active_record"].find
|
467
|
+
assert_equal 3, @developers["jamis"].find.projects.size
|
468
|
+
assert_equal 1, @developers["jamis"].find.projects.uniq.size
|
469
|
+
end
|
470
|
+
|
471
|
+
def test_uniq_before_the_fact
|
472
|
+
@projects["active_record"].find.developers << @developers["jamis"].find
|
473
|
+
@projects["active_record"].find.developers << @developers["david"].find
|
474
|
+
assert_equal 2, @projects["active_record"].find.developers.size
|
475
|
+
end
|
476
|
+
|
434
477
|
def test_deleting
|
435
478
|
david = Developer.find(1)
|
436
479
|
active_record = Project.find(1)
|
@@ -445,18 +488,18 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
445
488
|
assert_equal 1, active_record.developers(true).size
|
446
489
|
end
|
447
490
|
|
448
|
-
def
|
491
|
+
def test_deleting_array
|
449
492
|
david = Developer.find(1)
|
450
493
|
david.projects.id
|
451
494
|
david.projects.delete(Project.find_all)
|
452
495
|
assert_equal 0, david.projects.size
|
453
496
|
assert_equal 0, david.projects(true).size
|
454
497
|
end
|
455
|
-
|
456
|
-
def
|
498
|
+
|
499
|
+
def test_deleting_all
|
457
500
|
david = Developer.find(1)
|
458
501
|
david.projects.id
|
459
|
-
david.projects.
|
502
|
+
david.projects.clear
|
460
503
|
assert_equal 0, david.projects.size
|
461
504
|
assert_equal 0, david.projects(true).size
|
462
505
|
end
|
@@ -466,6 +509,10 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
466
509
|
assert Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = '1'").empty?
|
467
510
|
end
|
468
511
|
|
512
|
+
def test_additional_columns_from_join_table
|
513
|
+
assert_equal Date.new(2004, 10, 10).to_s, Developer.find(1).projects.first.joined_on.to_s
|
514
|
+
end
|
515
|
+
|
469
516
|
def test_destroy_all
|
470
517
|
david = Developer.find(1)
|
471
518
|
david.projects.id
|
@@ -474,4 +521,29 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
474
521
|
assert david.projects.empty?
|
475
522
|
assert david.projects(true).empty?
|
476
523
|
end
|
477
|
-
|
524
|
+
|
525
|
+
def test_rich_association
|
526
|
+
@jamis = @developers["jamis"].find
|
527
|
+
@jamis.projects.push_with_attributes(@projects["action_controller"].find, :joined_on => Date.today)
|
528
|
+
assert_equal Date.today.to_s, @jamis.projects.select { |p| p.name == @projects["action_controller"]["name"] }.first.joined_on.to_s
|
529
|
+
assert_equal Date.today.to_s, @developers["jamis"].find.projects.select { |p| p.name == @projects["action_controller"]["name"] }.first.joined_on.to_s
|
530
|
+
end
|
531
|
+
|
532
|
+
def test_associations_with_conditions
|
533
|
+
assert_equal 2, @projects["active_record"].find.developers.size
|
534
|
+
assert_equal 1, @projects["active_record"].find.developers_named_david.size
|
535
|
+
|
536
|
+
@projects["active_record"].find.developers_named_david.clear
|
537
|
+
assert_equal 1, @projects["active_record"].find.developers.size
|
538
|
+
end
|
539
|
+
|
540
|
+
def test_find_in_association
|
541
|
+
# Using sql
|
542
|
+
assert_equal @developers["david"].find, @projects["active_record"].find.developers.find(@developers["david"]["id"]), "SQL find"
|
543
|
+
|
544
|
+
# Using ruby
|
545
|
+
@active_record = @projects["active_record"].find
|
546
|
+
@active_record.developers.reload
|
547
|
+
assert_equal @developers["david"].find, @active_record.developers.find(@developers["david"]["id"]), "Ruby find"
|
548
|
+
end
|
549
|
+
end
|
data/test/base_test.rb
CHANGED
@@ -59,9 +59,13 @@ class BasicsTest < Test::Unit::TestCase
|
|
59
59
|
assert topic.respond_to?("title")
|
60
60
|
assert topic.respond_to?("title?")
|
61
61
|
assert topic.respond_to?("title=")
|
62
|
+
assert topic.respond_to?(:title)
|
63
|
+
assert topic.respond_to?(:title?)
|
64
|
+
assert topic.respond_to?(:title=)
|
62
65
|
assert topic.respond_to?("author_name")
|
63
66
|
assert topic.respond_to?("attribute_names")
|
64
67
|
assert !topic.respond_to?("nothingness")
|
68
|
+
assert !topic.respond_to?(:nothingness)
|
65
69
|
end
|
66
70
|
|
67
71
|
def test_array_content
|
@@ -325,6 +329,10 @@ class BasicsTest < Test::Unit::TestCase
|
|
325
329
|
assert_equal Topic.find(1), Topic.find(2).parent
|
326
330
|
end
|
327
331
|
|
332
|
+
def test_hashing
|
333
|
+
assert_equal [ Topic.find(1) ], [ Topic.find(2).parent ] & [ Topic.find(1) ]
|
334
|
+
end
|
335
|
+
|
328
336
|
def test_destroy_new_record
|
329
337
|
client = Client.new
|
330
338
|
client.destroy
|
@@ -510,4 +518,10 @@ class BasicsTest < Test::Unit::TestCase
|
|
510
518
|
assert_equal(settings, Topic.find(topic.id).content)
|
511
519
|
Topic.serialize(:content)
|
512
520
|
end
|
513
|
-
|
521
|
+
|
522
|
+
def test_quote
|
523
|
+
content = "\\ \001 ' \n \\n \""
|
524
|
+
topic = Topic.create('content' => content)
|
525
|
+
assert_equal content, Topic.find(topic.id).content
|
526
|
+
end
|
527
|
+
end
|
@@ -3,22 +3,32 @@ require 'fixtures/course'
|
|
3
3
|
require 'logger'
|
4
4
|
ActiveRecord::Base.logger = Logger.new("debug.log")
|
5
5
|
|
6
|
-
|
7
|
-
sqlite_test_db = "#{
|
8
|
-
sqlite_test_db2 = "#{
|
6
|
+
BASE_DIR = File.expand_path(File.dirname(__FILE__) + '/../../fixtures')
|
7
|
+
sqlite_test_db = "#{BASE_DIR}/fixture_database.sqlite"
|
8
|
+
sqlite_test_db2 = "#{BASE_DIR}/fixture_database_2.sqlite"
|
9
9
|
|
10
|
-
|
11
|
-
unless File.exist?(
|
12
|
-
puts "
|
13
|
-
|
10
|
+
def make_connection(clazz, db_file, db_definitions_file)
|
11
|
+
unless File.exist?(db_file)
|
12
|
+
puts "SQLite database not found at #{db_file}. Rebuilding it."
|
13
|
+
sqlite_command = "sqlite #{db_file} 'create table a (a integer); drop table a;'"
|
14
|
+
puts "Executing '#{sqlite_command}'"
|
15
|
+
`#{sqlite_command}`
|
16
|
+
clazz.establish_connection(
|
17
|
+
:adapter => "sqlite",
|
18
|
+
:dbfile => db_file)
|
19
|
+
script = File.read("#{BASE_DIR}/db_definitions/#{db_definitions_file}")
|
20
|
+
# SQLite-Ruby has problems with semi-colon separated commands, so split and execute one at a time
|
21
|
+
script.split(';').each do
|
22
|
+
|command|
|
23
|
+
clazz.connection.execute(command) unless command.strip.empty?
|
24
|
+
end
|
14
25
|
else
|
15
|
-
|
26
|
+
clazz.establish_connection(
|
27
|
+
:adapter => "sqlite",
|
28
|
+
:dbfile => db_file)
|
16
29
|
end
|
17
30
|
end
|
18
31
|
|
19
|
-
ActiveRecord::Base.
|
20
|
-
|
21
|
-
|
22
|
-
Course.establish_connection(
|
23
|
-
:adapter => "sqlite",
|
24
|
-
:dbfile => sqlite_test_db2)
|
32
|
+
make_connection(ActiveRecord::Base, sqlite_test_db, 'sqlite.sql')
|
33
|
+
make_connection(Course, sqlite_test_db2, 'sqlite2.sql')
|
34
|
+
|
@@ -99,13 +99,11 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
|
|
99
99
|
def test_belongs_to_with_different_class_name
|
100
100
|
assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
|
101
101
|
assert Company.find(3).has_firm_with_other_name?, "Microsoft should have a firm"
|
102
|
-
assert !Company.find(1).has_firm_with_other_name?, "37signals shouldn't have a firm"
|
103
102
|
end
|
104
103
|
|
105
104
|
def test_belongs_to_with_condition
|
106
105
|
assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
|
107
106
|
assert Company.find(3).has_firm_with_condition?, "Microsoft should have a firm"
|
108
|
-
assert !Company.find(1).has_firm_with_condition?, "37signals shouldn't have a firm"
|
109
107
|
end
|
110
108
|
|
111
109
|
|
@@ -314,16 +312,17 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
|
|
314
312
|
|
315
313
|
def test_storing_in_pstore
|
316
314
|
require "pstore"
|
315
|
+
require "tmpdir"
|
317
316
|
apple = Firm.create("name" => "Apple")
|
318
317
|
natural = Client.new("name" => "Natural Company")
|
319
318
|
apple.clients << natural
|
320
319
|
|
321
|
-
db = PStore.new("
|
320
|
+
db = PStore.new(File.join(Dir.tmpdir, "ar-pstore-association-test"))
|
322
321
|
db.transaction do
|
323
322
|
db["apple"] = apple
|
324
323
|
end
|
325
324
|
|
326
|
-
db = PStore.new("
|
325
|
+
db = PStore.new(File.join(Dir.tmpdir, "ar-pstore-association-test"))
|
327
326
|
db.transaction do
|
328
327
|
assert_equal "Natural Company", db["apple"].clients.first.name
|
329
328
|
end
|
@@ -0,0 +1,334 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/developer'
|
3
|
+
require 'fixtures/project'
|
4
|
+
require 'fixtures/company'
|
5
|
+
require 'fixtures/topic'
|
6
|
+
# require File.dirname(__FILE__) + '/../dev-utils/eval_debugger'
|
7
|
+
require 'fixtures/reply'
|
8
|
+
|
9
|
+
# Can't declare new classes in test case methods, so tests before that
|
10
|
+
bad_collection_keys = false
|
11
|
+
begin
|
12
|
+
class Car < ActiveRecord::Base; has_many :wheels, :name => "wheels"; end
|
13
|
+
rescue ActiveRecord::ActiveRecordError
|
14
|
+
bad_collection_keys = true
|
15
|
+
end
|
16
|
+
raise "ActiveRecord should have barked on bad collection keys" unless bad_collection_keys
|
17
|
+
|
18
|
+
|
19
|
+
class DeprecatedAssociationsTest < Test::Unit::TestCase
|
20
|
+
def setup
|
21
|
+
create_fixtures "accounts", "companies", "accounts", "developers", "projects", "developers_projects", "topics"
|
22
|
+
@signals37 = Firm.find(1)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_has_many_find
|
26
|
+
assert_equal 2, Firm.find_first.clients.length
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_has_many_orders
|
30
|
+
assert_equal "Summit", Firm.find_first.clients.first.name
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_has_many_class_name
|
34
|
+
assert_equal "Microsoft", Firm.find_first.clients_sorted_desc.first.name
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_has_many_foreign_key
|
38
|
+
assert_equal "Microsoft", Firm.find_first.clients_of_firm.first.name
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_has_many_conditions
|
42
|
+
assert_equal "Microsoft", Firm.find_first.clients_like_ms.first.name
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_has_many_sql
|
46
|
+
firm = Firm.find_first
|
47
|
+
assert_equal "Microsoft", firm.clients_using_sql.first.name
|
48
|
+
assert_equal 1, firm.clients_using_sql_count
|
49
|
+
assert_equal 1, Firm.find_first.clients_using_sql_count
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_has_many_queries
|
53
|
+
assert Firm.find_first.has_clients?
|
54
|
+
firm = Firm.find_first
|
55
|
+
assert_equal 2, firm.clients_count # tests using class count
|
56
|
+
firm.clients
|
57
|
+
assert firm.has_clients?
|
58
|
+
assert_equal 2, firm.clients_count # tests using collection length
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_has_many_dependence
|
62
|
+
assert_equal 2, Client.find_all.length
|
63
|
+
Firm.find_first.destroy
|
64
|
+
assert_equal 0, Client.find_all.length
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_has_many_dependence_with_transaction_support_on_failure
|
68
|
+
assert_equal 2, Client.find_all.length
|
69
|
+
|
70
|
+
firm = Firm.find_first
|
71
|
+
clients = firm.clients
|
72
|
+
clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end }
|
73
|
+
|
74
|
+
firm.destroy rescue "do nothing"
|
75
|
+
|
76
|
+
assert_equal 2, Client.find_all.length
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_has_one_dependence
|
80
|
+
firm = Firm.find(1)
|
81
|
+
assert firm.has_account?
|
82
|
+
firm.destroy
|
83
|
+
assert_equal 1, Account.find_all.length
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_has_one_dependence_with_missing_association
|
87
|
+
Account.destroy_all
|
88
|
+
firm = Firm.find(1)
|
89
|
+
assert !firm.has_account?
|
90
|
+
firm.destroy
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_belongs_to
|
94
|
+
assert_equal @signals37.name, Client.find(3).firm.name
|
95
|
+
assert Client.find(3).has_firm?, "Microsoft should have a firm"
|
96
|
+
# assert !Company.find(1).has_firm?, "37signals shouldn't have a firm"
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_belongs_to_with_different_class_name
|
100
|
+
assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
|
101
|
+
assert Company.find(3).has_firm_with_other_name?, "Microsoft should have a firm"
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_belongs_to_with_condition
|
105
|
+
assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
|
106
|
+
assert Company.find(3).has_firm_with_condition?, "Microsoft should have a firm"
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
def test_belongs_to_equality
|
111
|
+
assert Company.find(3).firm?(Company.find(1)), "Microsoft should have 37signals as firm"
|
112
|
+
assert_raises(RuntimeError) { !Company.find(3).firm?(Company.find(3)) } # "Summit shouldn't have itself as firm"
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_has_one
|
116
|
+
assert @signals37.account?(Account.find(1))
|
117
|
+
assert_equal Account.find(1).credit_limit, @signals37.account.credit_limit
|
118
|
+
assert @signals37.has_account?, "37signals should have an account"
|
119
|
+
assert Account.find(1).firm?(@signals37), "37signals account should be able to backtrack"
|
120
|
+
assert Account.find(1).has_firm?, "37signals account should be able to backtrack"
|
121
|
+
|
122
|
+
assert !Account.find(2).has_firm?, "Unknown isn't linked"
|
123
|
+
assert !Account.find(2).firm?(@signals37), "Unknown isn't linked"
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_has_many_dependence_on_account
|
127
|
+
assert_equal 2, Account.find_all.length
|
128
|
+
@signals37.destroy
|
129
|
+
assert_equal 1, Account.find_all.length
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_find_in
|
133
|
+
assert_equal Client.find(2).name, @signals37.find_in_clients(2).name
|
134
|
+
assert_raises(ActiveRecord::RecordNotFound) { @signals37.find_in_clients(6) }
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_force_reload
|
138
|
+
firm = Firm.new
|
139
|
+
firm.save
|
140
|
+
firm.clients.each {|c|} # forcing to load all clients
|
141
|
+
assert firm.clients.empty?, "New firm shouldn't have client objects"
|
142
|
+
assert !firm.has_clients?, "New firm shouldn't have clients"
|
143
|
+
assert_equal 0, firm.clients_count, "New firm should have 0 clients"
|
144
|
+
|
145
|
+
client = Client.new("firm_id" => firm.id)
|
146
|
+
client.save
|
147
|
+
|
148
|
+
assert firm.clients.empty?, "New firm should have cached no client objects"
|
149
|
+
assert !firm.has_clients?, "New firm should have cached a no-clients response"
|
150
|
+
assert_equal 0, firm.clients_count, "New firm should have cached 0 clients count"
|
151
|
+
|
152
|
+
assert !firm.clients(true).empty?, "New firm should have reloaded client objects"
|
153
|
+
assert firm.has_clients?(true), "New firm should have reloaded with a have-clients response"
|
154
|
+
assert_equal 1, firm.clients_count(true), "New firm should have reloaded clients count"
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_included_in_collection
|
158
|
+
assert @signals37.clients.include?(Client.find(2))
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_build_to_collection
|
162
|
+
assert_equal 1, @signals37.clients_of_firm_count
|
163
|
+
new_client = @signals37.build_to_clients_of_firm("name" => "Another Client")
|
164
|
+
assert_equal "Another Client", new_client.name
|
165
|
+
assert new_client.save
|
166
|
+
|
167
|
+
assert new_client.firm?(@signals37)
|
168
|
+
assert_equal 2, @signals37.clients_of_firm_count(true)
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_create_in_collection
|
172
|
+
assert_equal @signals37.create_in_clients_of_firm("name" => "Another Client"), @signals37.clients_of_firm(true).last
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_succesful_build_association
|
176
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
177
|
+
firm.save
|
178
|
+
|
179
|
+
account = firm.build_account("credit_limit" => 1000)
|
180
|
+
assert account.save
|
181
|
+
assert_equal account, firm.account
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_failing_build_association
|
185
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
186
|
+
firm.save
|
187
|
+
|
188
|
+
account = firm.build_account
|
189
|
+
assert !account.save
|
190
|
+
assert_equal "can't be empty", account.errors.on("credit_limit")
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_create_association
|
194
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
195
|
+
firm.save
|
196
|
+
assert_equal firm.create_account("credit_limit" => 1000), firm.account
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_has_and_belongs_to_many
|
200
|
+
david = Developer.find(1)
|
201
|
+
assert david.has_projects?
|
202
|
+
assert_equal 2, david.projects_count
|
203
|
+
|
204
|
+
active_record = Project.find(1)
|
205
|
+
assert active_record.has_developers?
|
206
|
+
assert_equal 2, active_record.developers_count
|
207
|
+
assert_equal david.name, active_record.developers.first.name
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_has_and_belongs_to_many_removing
|
211
|
+
david = Developer.find(1)
|
212
|
+
active_record = Project.find(1)
|
213
|
+
|
214
|
+
david.remove_projects(active_record)
|
215
|
+
|
216
|
+
assert_equal 1, david.projects_count
|
217
|
+
assert_equal 1, active_record.developers_count
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_has_and_belongs_to_many_zero
|
221
|
+
david = Developer.find(1)
|
222
|
+
david.remove_projects(Project.find_all)
|
223
|
+
|
224
|
+
assert_equal 0, david.projects_count
|
225
|
+
assert !david.has_projects?
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_has_and_belongs_to_many_adding
|
229
|
+
jamis = Developer.find(2)
|
230
|
+
action_controller = Project.find(2)
|
231
|
+
|
232
|
+
jamis.add_projects(action_controller)
|
233
|
+
|
234
|
+
assert_equal 2, jamis.projects_count
|
235
|
+
assert_equal 2, action_controller.developers_count
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_has_and_belongs_to_many_adding_from_the_project
|
239
|
+
jamis = Developer.find(2)
|
240
|
+
action_controller = Project.find(2)
|
241
|
+
|
242
|
+
action_controller.add_developers(jamis)
|
243
|
+
|
244
|
+
assert_equal 2, jamis.projects_count
|
245
|
+
assert_equal 2, action_controller.developers_count
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_has_and_belongs_to_many_adding_a_collection
|
249
|
+
aridridel = Developer.new("name" => "Aridridel")
|
250
|
+
aridridel.save
|
251
|
+
|
252
|
+
aridridel.add_projects([ Project.find(1), Project.find(2) ])
|
253
|
+
assert_equal 2, aridridel.projects_count
|
254
|
+
end
|
255
|
+
|
256
|
+
def test_belongs_to_counter
|
257
|
+
topic = Topic.create("title" => "Apple", "content" => "hello world")
|
258
|
+
assert_equal 0, topic.send(:read_attribute, "replies_count"), "No replies yet"
|
259
|
+
|
260
|
+
reply = topic.create_in_replies("title" => "I'm saying no!", "content" => "over here")
|
261
|
+
assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count"), "First reply created"
|
262
|
+
|
263
|
+
reply.destroy
|
264
|
+
assert_equal 0, Topic.find(topic.id).send(:read_attribute, "replies_count"), "First reply deleted"
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_natural_assignment_of_has_one
|
268
|
+
apple = Firm.create("name" => "Apple")
|
269
|
+
citibank = Account.create("credit_limit" => 10)
|
270
|
+
apple.account = citibank
|
271
|
+
assert_equal apple.id, citibank.firm_id
|
272
|
+
end
|
273
|
+
|
274
|
+
def test_natural_assignment_of_belongs_to
|
275
|
+
apple = Firm.create("name" => "Apple")
|
276
|
+
citibank = Account.create("credit_limit" => 10)
|
277
|
+
citibank.firm = apple
|
278
|
+
assert_equal apple.id, citibank.firm_id
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_natural_assignment_of_has_many
|
282
|
+
apple = Firm.create("name" => "Apple")
|
283
|
+
natural = Client.new("name" => "Natural Company")
|
284
|
+
apple.clients << natural
|
285
|
+
assert_equal apple.id, natural.firm_id
|
286
|
+
assert_equal Client.find(natural.id), Firm.find(apple.id).clients.find { |c| c.id == natural.id }
|
287
|
+
apple.clients.delete natural
|
288
|
+
assert_nil Firm.find(apple.id).clients.find { |c| c.id == natural.id }
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
def test_natural_adding_of_has_and_belongs_to_many
|
293
|
+
rails = Project.create("name" => "Rails")
|
294
|
+
ap = Project.create("name" => "Action Pack")
|
295
|
+
john = Developer.create("name" => "John")
|
296
|
+
mike = Developer.create("name" => "Mike")
|
297
|
+
rails.developers << john
|
298
|
+
rails.developers << mike
|
299
|
+
|
300
|
+
assert_equal Developer.find(john.id), Project.find(rails.id).developers.find { |d| d.id == john.id }
|
301
|
+
assert_equal Developer.find(mike.id), Project.find(rails.id).developers.find { |d| d.id == mike.id }
|
302
|
+
assert_equal Project.find(rails.id), Developer.find(mike.id).projects.find { |p| p.id == rails.id }
|
303
|
+
assert_equal Project.find(rails.id), Developer.find(john.id).projects.find { |p| p.id == rails.id }
|
304
|
+
ap.developers << john
|
305
|
+
assert_equal Developer.find(john.id), Project.find(ap.id).developers.find { |d| d.id == john.id }
|
306
|
+
assert_equal Project.find(ap.id), Developer.find(john.id).projects.find { |p| p.id == ap.id }
|
307
|
+
|
308
|
+
ap.developers.delete john
|
309
|
+
assert_nil Project.find(ap.id).developers.find { |d| d.id == john.id }
|
310
|
+
assert_nil Developer.find(john.id).projects.find { |p| p.id == ap.id }
|
311
|
+
end
|
312
|
+
|
313
|
+
def test_storing_in_pstore
|
314
|
+
require "pstore"
|
315
|
+
apple = Firm.create("name" => "Apple")
|
316
|
+
natural = Client.new("name" => "Natural Company")
|
317
|
+
apple.clients << natural
|
318
|
+
|
319
|
+
db = PStore.new("/tmp/ar-pstore-association-test")
|
320
|
+
db.transaction do
|
321
|
+
db["apple"] = apple
|
322
|
+
end
|
323
|
+
|
324
|
+
db = PStore.new("/tmp/ar-pstore-association-test")
|
325
|
+
db.transaction do
|
326
|
+
assert_equal "Natural Company", db["apple"].clients.first.name
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_has_many_find_all
|
331
|
+
assert_equal 2, Firm.find_first.find_all_in_clients("type = 'Client'").length
|
332
|
+
assert_equal 1, Firm.find_first.find_all_in_clients("name = 'Summit'").length
|
333
|
+
end
|
334
|
+
end
|