activerecord 2.1.0 → 2.1.1
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 +34 -0
- data/README +0 -0
- data/Rakefile +6 -5
- data/lib/active_record.rb +8 -10
- data/lib/active_record/association_preload.rb +17 -12
- data/lib/active_record/associations.rb +45 -27
- data/lib/active_record/associations/association_collection.rb +8 -5
- data/lib/active_record/associations/association_proxy.rb +2 -6
- data/lib/active_record/associations/belongs_to_association.rb +0 -0
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +2 -3
- data/lib/active_record/associations/has_many_association.rb +16 -4
- data/lib/active_record/associations/has_many_through_association.rb +1 -1
- data/lib/active_record/associations/has_one_association.rb +2 -2
- data/lib/active_record/associations/has_one_through_association.rb +4 -0
- data/lib/active_record/base.rb +33 -15
- data/lib/active_record/calculations.rb +20 -7
- data/lib/active_record/callbacks.rb +0 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +9 -6
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +17 -10
- data/lib/active_record/connection_adapters/abstract_adapter.rb +0 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +53 -24
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +66 -20
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +12 -0
- data/lib/active_record/dirty.rb +10 -3
- data/lib/active_record/fixtures.rb +0 -0
- data/lib/active_record/locking/optimistic.rb +1 -0
- data/lib/active_record/migration.rb +35 -8
- data/lib/active_record/named_scope.rb +6 -1
- data/lib/active_record/observer.rb +7 -5
- data/lib/active_record/test_case.rb +13 -2
- data/lib/active_record/validations.rb +19 -9
- data/lib/active_record/version.rb +1 -1
- data/test/cases/active_schema_test_postgresql.rb +2 -2
- data/test/cases/adapter_test.rb +1 -1
- data/test/cases/associations/belongs_to_associations_test.rb +19 -0
- data/test/cases/associations/cascaded_eager_loading_test.rb +13 -1
- data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -0
- data/test/cases/associations/eager_test.rb +25 -1
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +27 -5
- data/test/cases/associations/has_many_associations_test.rb +106 -4
- data/test/cases/associations/has_many_through_associations_test.rb +10 -0
- data/test/cases/associations/has_one_associations_test.rb +22 -0
- data/test/cases/associations/has_one_through_associations_test.rb +44 -5
- data/test/cases/associations/join_model_test.rb +7 -0
- data/test/cases/associations_test.rb +2 -2
- data/test/cases/attribute_methods_test.rb +10 -10
- data/test/cases/base_test.rb +39 -16
- data/test/cases/calculations_test.rb +53 -1
- data/test/cases/column_definition_test.rb +36 -0
- data/test/cases/database_statements_test.rb +12 -0
- data/test/cases/defaults_test.rb +1 -1
- data/test/cases/deprecated_finder_test.rb +0 -0
- data/test/cases/dirty_test.rb +94 -0
- data/test/cases/finder_test.rb +7 -0
- data/test/cases/fixtures_test.rb +0 -0
- data/test/cases/helper.rb +5 -5
- data/test/cases/inheritance_test.rb +9 -2
- data/test/cases/lifecycle_test.rb +54 -1
- data/test/cases/locking_test.rb +20 -0
- data/test/cases/method_scoping_test.rb +11 -1
- data/test/cases/migration_test.rb +147 -22
- data/test/cases/multiple_db_test.rb +1 -1
- data/test/cases/named_scope_test.rb +50 -1
- data/test/cases/query_cache_test.rb +4 -3
- data/test/cases/readonly_test.rb +0 -0
- data/test/cases/reflection_test.rb +3 -3
- data/test/cases/schema_dumper_test.rb +46 -0
- data/test/cases/unconnected_test.rb +0 -0
- data/test/cases/validations_test.rb +30 -5
- data/test/debug.log +358 -0
- data/test/fixtures/fixture_database.sqlite3 +0 -0
- data/test/fixtures/fixture_database_2.sqlite3 +0 -0
- data/test/models/author.rb +4 -0
- data/test/models/category.rb +1 -0
- data/test/models/company.rb +10 -1
- data/test/models/developer.rb +4 -1
- data/test/models/person.rb +1 -1
- data/test/models/post.rb +6 -1
- data/test/models/project.rb +1 -1
- data/test/models/reply.rb +0 -0
- data/test/models/topic.rb +1 -0
- data/test/schema/mysql_specific_schema.rb +2 -2
- data/test/schema/schema.rb +8 -0
- metadata +11 -5
- data/lib/active_record/vendor/db2.rb +0 -362
@@ -13,8 +13,8 @@ class PostgresqlActiveSchemaTest < Test::Unit::TestCase
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_create_database_with_encoding
|
16
|
-
assert_equal
|
17
|
-
assert_equal
|
16
|
+
assert_equal %(CREATE DATABASE "matt" ENCODING = 'utf8'), create_database(:matt)
|
17
|
+
assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, :encoding => :latin1)
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
data/test/cases/adapter_test.rb
CHANGED
@@ -118,7 +118,7 @@ class AdapterTest < ActiveRecord::TestCase
|
|
118
118
|
sql_inject = "1, 7 procedure help()"
|
119
119
|
if current_adapter?(:MysqlAdapter)
|
120
120
|
assert_equal " LIMIT 1,7", @connection.add_limit_offset!("", :limit=>sql_inject)
|
121
|
-
assert_equal " LIMIT 7, 1", @connection.add_limit_offset!("", :limit=>
|
121
|
+
assert_equal " LIMIT 7, 1", @connection.add_limit_offset!("", :limit=> '1 ; DROP TABLE USERS', :offset=>7)
|
122
122
|
else
|
123
123
|
assert_equal " LIMIT 1,7", @connection.add_limit_offset!("", :limit=>sql_inject)
|
124
124
|
assert_equal " LIMIT 1,7 OFFSET 7", @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
|
@@ -409,4 +409,23 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
409
409
|
sponsor.sponsorable = new_member
|
410
410
|
assert_equal nil, sponsor.sponsorable_id
|
411
411
|
end
|
412
|
+
|
413
|
+
def test_save_fails_for_invalid_belongs_to
|
414
|
+
assert log = AuditLog.create(:developer_id=>0,:message=>"")
|
415
|
+
|
416
|
+
log.developer = Developer.new
|
417
|
+
assert !log.developer.valid?
|
418
|
+
assert !log.valid?
|
419
|
+
assert !log.save
|
420
|
+
assert_equal "is invalid", log.errors.on("developer")
|
421
|
+
end
|
422
|
+
|
423
|
+
def test_save_succeeds_for_invalid_belongs_to_with_validate_false
|
424
|
+
assert log = AuditLog.create(:developer_id=>0,:message=>"")
|
425
|
+
|
426
|
+
log.unvalidated_developer = Developer.new
|
427
|
+
assert !log.unvalidated_developer.valid?
|
428
|
+
assert log.valid?
|
429
|
+
assert log.save
|
430
|
+
end
|
412
431
|
end
|
@@ -9,7 +9,7 @@ require 'models/topic'
|
|
9
9
|
require 'models/reply'
|
10
10
|
|
11
11
|
class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
12
|
-
fixtures :authors, :mixins, :companies, :posts, :topics
|
12
|
+
fixtures :authors, :mixins, :companies, :posts, :topics, :accounts, :comments, :categorizations
|
13
13
|
|
14
14
|
def test_eager_association_loading_with_cascaded_two_levels
|
15
15
|
authors = Author.find(:all, :include=>{:posts=>:comments}, :order=>"authors.id")
|
@@ -68,6 +68,18 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
def test_eager_association_loading_with_has_many_sti_and_subclasses
|
72
|
+
silly = SillyReply.new(:title => "gaga", :content => "boo-boo", :parent_id => 1)
|
73
|
+
silly.parent_id = 1
|
74
|
+
assert silly.save
|
75
|
+
|
76
|
+
topics = Topic.find(:all, :include => :replies, :order => 'topics.id, replies_topics.id')
|
77
|
+
assert_no_queries do
|
78
|
+
assert_equal 2, topics[0].replies.size
|
79
|
+
assert_equal 0, topics[1].replies.size
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
71
83
|
def test_eager_association_loading_with_belongs_to_sti
|
72
84
|
replies = Reply.find(:all, :include => :topic, :order => 'topics.id')
|
73
85
|
assert replies.include?(topics(:second))
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'cases/helper'
|
2
|
+
require 'models/post'
|
3
|
+
require 'models/tagging'
|
4
|
+
|
5
|
+
module Namespaced
|
6
|
+
class Post < ActiveRecord::Base
|
7
|
+
set_table_name 'posts'
|
8
|
+
has_one :tagging, :as => :taggable, :class_name => 'Tagging'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class EagerLoadIncludeFullStiClassNamesTest < ActiveRecord::TestCase
|
13
|
+
|
14
|
+
def setup
|
15
|
+
generate_test_objects
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_test_objects
|
19
|
+
post = Namespaced::Post.create( :title => 'Great stuff', :body => 'This is not', :author_id => 1 )
|
20
|
+
tagging = Tagging.create( :taggable => post )
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_class_names
|
24
|
+
old = ActiveRecord::Base.store_full_sti_class
|
25
|
+
|
26
|
+
ActiveRecord::Base.store_full_sti_class = false
|
27
|
+
post = Namespaced::Post.find_by_title( 'Great stuff', :include => :tagging )
|
28
|
+
assert_nil post.tagging
|
29
|
+
|
30
|
+
ActiveRecord::Base.store_full_sti_class = true
|
31
|
+
post = Namespaced::Post.find_by_title( 'Great stuff', :include => :tagging )
|
32
|
+
assert_equal 'Tagging', post.tagging.class.name
|
33
|
+
ensure
|
34
|
+
ActiveRecord::Base.store_full_sti_class = old
|
35
|
+
end
|
36
|
+
end
|
@@ -14,11 +14,14 @@ require 'models/job'
|
|
14
14
|
require 'models/subscriber'
|
15
15
|
require 'models/subscription'
|
16
16
|
require 'models/book'
|
17
|
+
require 'models/developer'
|
18
|
+
require 'models/project'
|
17
19
|
|
18
20
|
class EagerAssociationTest < ActiveRecord::TestCase
|
19
21
|
fixtures :posts, :comments, :authors, :categories, :categories_posts,
|
20
22
|
:companies, :accounts, :tags, :taggings, :people, :readers,
|
21
|
-
:owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books
|
23
|
+
:owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books,
|
24
|
+
:developers, :projects, :developers_projects
|
22
25
|
|
23
26
|
def test_loading_with_one_association
|
24
27
|
posts = Post.find(:all, :include => :comments)
|
@@ -35,6 +38,12 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
|
35
38
|
assert_equal Post.find(1).last_comment, post.last_comment
|
36
39
|
end
|
37
40
|
|
41
|
+
def test_loading_with_one_association_with_non_preload
|
42
|
+
posts = Post.find(:all, :include => :last_comment, :order => 'comments.id DESC')
|
43
|
+
post = posts.find { |p| p.id == 1 }
|
44
|
+
assert_equal Post.find(1).last_comment, post.last_comment
|
45
|
+
end
|
46
|
+
|
38
47
|
def test_loading_conditions_with_or
|
39
48
|
posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'")
|
40
49
|
assert_nil posts.detect { |p| p.author_id != authors(:david).id },
|
@@ -556,6 +565,13 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
|
556
565
|
assert_nothing_raised { Post.find(:all, :include => 'comments') }
|
557
566
|
end
|
558
567
|
|
568
|
+
def test_eager_with_floating_point_numbers
|
569
|
+
assert_queries(2) do
|
570
|
+
# Before changes, the floating point numbers will be interpreted as table names and will cause this to run in one query
|
571
|
+
Comment.find :all, :conditions => "123.456 = 123.456", :include => :post
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
559
575
|
def test_preconfigured_includes_with_belongs_to
|
560
576
|
author = posts(:welcome).author_with_posts
|
561
577
|
assert_no_queries {assert_equal 5, author.posts.size}
|
@@ -609,4 +625,12 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
|
609
625
|
Comment.find :all, :include => :post
|
610
626
|
end
|
611
627
|
end
|
628
|
+
|
629
|
+
def test_conditions_on_join_table_with_include_and_limit
|
630
|
+
assert_equal 3, Developer.find(:all, :include => 'projects', :conditions => 'developers_projects.access_level = 1', :limit => 5).size
|
631
|
+
end
|
632
|
+
|
633
|
+
def test_order_on_join_table_with_include_and_limit
|
634
|
+
assert_equal 5, Developer.find(:all, :include => 'projects', :order => 'developers_projects.joined_on DESC', :limit => 5).size
|
635
|
+
end
|
612
636
|
end
|
@@ -70,7 +70,7 @@ end
|
|
70
70
|
|
71
71
|
class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
72
72
|
fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
|
73
|
-
:parrots, :pirates, :treasures, :price_estimates
|
73
|
+
:parrots, :pirates, :treasures, :price_estimates, :tags, :taggings
|
74
74
|
|
75
75
|
def test_has_and_belongs_to_many
|
76
76
|
david = Developer.find(1)
|
@@ -299,6 +299,17 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
299
299
|
assert_equal 3, projects(:active_record, :reload).developers.size
|
300
300
|
end
|
301
301
|
|
302
|
+
def test_uniq_option_prevents_duplicate_push
|
303
|
+
project = projects(:active_record)
|
304
|
+
project.developers << developers(:jamis)
|
305
|
+
project.developers << developers(:david)
|
306
|
+
assert_equal 3, project.developers.size
|
307
|
+
|
308
|
+
project.developers << developers(:david)
|
309
|
+
project.developers << developers(:jamis)
|
310
|
+
assert_equal 3, project.developers.size
|
311
|
+
end
|
312
|
+
|
302
313
|
def test_deleting
|
303
314
|
david = Developer.find(1)
|
304
315
|
active_record = Project.find(1)
|
@@ -439,6 +450,13 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
439
450
|
assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find"
|
440
451
|
end
|
441
452
|
|
453
|
+
def test_find_in_association_with_custom_finder_sql_and_multiple_interpolations
|
454
|
+
# interpolate once:
|
455
|
+
assert_equal [developers(:david), developers(:jamis), developers(:poor_jamis)], projects(:active_record).developers_with_finder_sql, "first interpolation"
|
456
|
+
# interpolate again, for a different project id
|
457
|
+
assert_equal [developers(:david)], projects(:action_controller).developers_with_finder_sql, "second interpolation"
|
458
|
+
end
|
459
|
+
|
442
460
|
def test_find_in_association_with_custom_finder_sql_and_string_id
|
443
461
|
assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id.to_s), "SQL find"
|
444
462
|
end
|
@@ -629,8 +647,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
629
647
|
developer.save
|
630
648
|
developer.reload
|
631
649
|
assert_equal 2, developer.projects.length
|
632
|
-
assert_equal projects(:active_record), developer.
|
633
|
-
assert_equal projects(:action_controller), developer.projects[1]
|
650
|
+
assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort
|
634
651
|
end
|
635
652
|
|
636
653
|
def test_assign_ids_ignoring_blanks
|
@@ -639,8 +656,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
639
656
|
developer.save
|
640
657
|
developer.reload
|
641
658
|
assert_equal 2, developer.projects.length
|
642
|
-
assert_equal projects(:active_record), developer.
|
643
|
-
assert_equal projects(:action_controller), developer.projects[1]
|
659
|
+
assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort
|
644
660
|
end
|
645
661
|
|
646
662
|
def test_select_limited_ids_list
|
@@ -681,4 +697,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
681
697
|
assert_equal developer, project.developers.find(:first)
|
682
698
|
assert_equal project, developer.projects.find(:first)
|
683
699
|
end
|
700
|
+
|
701
|
+
def test_dynamic_find_should_respect_association_include
|
702
|
+
# SQL error in sort clause if :include is not included
|
703
|
+
# due to Unknown column 'authors.id'
|
704
|
+
assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog')
|
705
|
+
end
|
684
706
|
end
|
@@ -14,7 +14,7 @@ require 'models/reader'
|
|
14
14
|
class HasManyAssociationsTest < ActiveRecord::TestCase
|
15
15
|
fixtures :accounts, :categories, :companies, :developers, :projects,
|
16
16
|
:developers_projects, :topics, :authors, :comments, :author_addresses,
|
17
|
-
:people, :posts
|
17
|
+
:people, :posts, :readers
|
18
18
|
|
19
19
|
def setup
|
20
20
|
Client.destroyed_client_ids.clear
|
@@ -37,15 +37,21 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def test_counting_with_single_conditions
|
40
|
-
assert_equal
|
40
|
+
assert_equal 1, Firm.find(:first).plain_clients.count(:conditions => ['name=?', "Microsoft"])
|
41
41
|
end
|
42
42
|
|
43
43
|
def test_counting_with_single_hash
|
44
|
-
assert_equal
|
44
|
+
assert_equal 1, Firm.find(:first).plain_clients.count(:conditions => {:name => "Microsoft"})
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_counting_with_column_name_and_hash
|
48
|
-
assert_equal 2, Firm.find(:first).plain_clients.count(:
|
48
|
+
assert_equal 2, Firm.find(:first).plain_clients.count(:name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_counting_with_association_limit
|
52
|
+
firm = companies(:first_firm)
|
53
|
+
assert_equal firm.limited_clients.length, firm.limited_clients.size
|
54
|
+
assert_equal firm.limited_clients.length, firm.limited_clients.count
|
49
55
|
end
|
50
56
|
|
51
57
|
def test_finding
|
@@ -342,6 +348,34 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
342
348
|
assert new_firm.new_record?
|
343
349
|
end
|
344
350
|
|
351
|
+
def test_invalid_adding_with_validate_false
|
352
|
+
firm = Firm.find(:first)
|
353
|
+
client = Client.new
|
354
|
+
firm.unvalidated_clients_of_firm << client
|
355
|
+
|
356
|
+
assert firm.valid?
|
357
|
+
assert !client.valid?
|
358
|
+
assert firm.save
|
359
|
+
assert client.new_record?
|
360
|
+
end
|
361
|
+
|
362
|
+
def test_valid_adding_with_validate_false
|
363
|
+
no_of_clients = Client.count
|
364
|
+
|
365
|
+
firm = Firm.find(:first)
|
366
|
+
client = Client.new("name" => "Apple")
|
367
|
+
|
368
|
+
assert firm.valid?
|
369
|
+
assert client.valid?
|
370
|
+
assert client.new_record?
|
371
|
+
|
372
|
+
firm.unvalidated_clients_of_firm << client
|
373
|
+
|
374
|
+
assert firm.save
|
375
|
+
assert !client.new_record?
|
376
|
+
assert_equal no_of_clients+1, Client.count
|
377
|
+
end
|
378
|
+
|
345
379
|
def test_build
|
346
380
|
company = companies(:first_firm)
|
347
381
|
new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
|
@@ -356,6 +390,25 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
356
390
|
assert_equal 2, company.clients_of_firm(true).size
|
357
391
|
end
|
358
392
|
|
393
|
+
def test_collection_size_after_building
|
394
|
+
company = companies(:first_firm) # company already has one client
|
395
|
+
company.clients_of_firm.build("name" => "Another Client")
|
396
|
+
company.clients_of_firm.build("name" => "Yet Another Client")
|
397
|
+
assert_equal 3, company.clients_of_firm.size
|
398
|
+
end
|
399
|
+
|
400
|
+
def test_collection_size_twice_for_regressions
|
401
|
+
post = posts(:thinking)
|
402
|
+
assert_equal 0, post.readers.size
|
403
|
+
# This test needs a post that has no readers, we assert it to ensure it holds,
|
404
|
+
# but need to reload the post because the very call to #size hides the bug.
|
405
|
+
post.reload
|
406
|
+
post.readers.build
|
407
|
+
size1 = post.readers.size
|
408
|
+
size2 = post.readers.size
|
409
|
+
assert_equal size1, size2
|
410
|
+
end
|
411
|
+
|
359
412
|
def test_build_many
|
360
413
|
company = companies(:first_firm)
|
361
414
|
new_clients = assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
|
@@ -386,6 +439,37 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
386
439
|
assert_equal 2, first_topic.replies.to_ary.size
|
387
440
|
end
|
388
441
|
|
442
|
+
def test_build_via_block
|
443
|
+
company = companies(:first_firm)
|
444
|
+
new_client = assert_no_queries { company.clients_of_firm.build {|client| client.name = "Another Client" } }
|
445
|
+
assert !company.clients_of_firm.loaded?
|
446
|
+
|
447
|
+
assert_equal "Another Client", new_client.name
|
448
|
+
assert new_client.new_record?
|
449
|
+
assert_equal new_client, company.clients_of_firm.last
|
450
|
+
company.name += '-changed'
|
451
|
+
assert_queries(2) { assert company.save }
|
452
|
+
assert !new_client.new_record?
|
453
|
+
assert_equal 2, company.clients_of_firm(true).size
|
454
|
+
end
|
455
|
+
|
456
|
+
def test_build_many_via_block
|
457
|
+
company = companies(:first_firm)
|
458
|
+
new_clients = assert_no_queries do
|
459
|
+
company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) do |client|
|
460
|
+
client.name = "changed"
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
assert_equal 2, new_clients.size
|
465
|
+
assert_equal "changed", new_clients.first.name
|
466
|
+
assert_equal "changed", new_clients.last.name
|
467
|
+
|
468
|
+
company.name += '-changed'
|
469
|
+
assert_queries(3) { assert company.save }
|
470
|
+
assert_equal 3, company.clients_of_firm(true).size
|
471
|
+
end
|
472
|
+
|
389
473
|
def test_create_without_loading_association
|
390
474
|
first_firm = companies(:first_firm)
|
391
475
|
Firm.column_names
|
@@ -929,4 +1013,22 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|
929
1013
|
assert firm.clients.loaded?
|
930
1014
|
end
|
931
1015
|
|
1016
|
+
def test_joins_with_namespaced_model_should_use_correct_type
|
1017
|
+
old = ActiveRecord::Base.store_full_sti_class
|
1018
|
+
ActiveRecord::Base.store_full_sti_class = true
|
1019
|
+
|
1020
|
+
firm = Namespaced::Firm.create({ :name => 'Some Company' })
|
1021
|
+
firm.clients.create({ :name => 'Some Client' })
|
1022
|
+
|
1023
|
+
stats = Namespaced::Firm.find(firm.id, {
|
1024
|
+
:select => "#{Namespaced::Firm.table_name}.id, COUNT(#{Namespaced::Client.table_name}.id) AS num_clients",
|
1025
|
+
:joins => :clients,
|
1026
|
+
:group => "#{Namespaced::Firm.table_name}.id"
|
1027
|
+
})
|
1028
|
+
assert_equal 1, stats.num_clients.to_i
|
1029
|
+
|
1030
|
+
ensure
|
1031
|
+
ActiveRecord::Base.store_full_sti_class = old
|
1032
|
+
end
|
1033
|
+
|
932
1034
|
end
|
@@ -187,4 +187,14 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
187
187
|
post.people_with_callbacks.clear
|
188
188
|
assert_equal (%w(Michael David Julian Roger) * 2).sort, log.last(8).collect(&:last).sort
|
189
189
|
end
|
190
|
+
|
191
|
+
def test_dynamic_find_should_respect_association_include
|
192
|
+
# SQL error in sort clause if :include is not included
|
193
|
+
# due to Unknown column 'comments.id'
|
194
|
+
assert Person.find(1).posts_with_comments_sorted_by_comment_id.find_by_title('Welcome to the weblog')
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_count_with_include_should_alias_join_table
|
198
|
+
assert_equal 2, people(:michael).posts.count(:include => :readers)
|
199
|
+
end
|
190
200
|
end
|
@@ -72,6 +72,16 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
|
72
72
|
assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
|
73
73
|
end
|
74
74
|
|
75
|
+
def test_natural_assignment_to_already_associated_record
|
76
|
+
company = companies(:first_firm)
|
77
|
+
account = accounts(:signals37)
|
78
|
+
assert_equal company.account, account
|
79
|
+
company.account = account
|
80
|
+
company.reload
|
81
|
+
account.reload
|
82
|
+
assert_equal company.account, account
|
83
|
+
end
|
84
|
+
|
75
85
|
def test_assignment_without_replacement
|
76
86
|
apple = Firm.create("name" => "Apple")
|
77
87
|
citibank = Account.create("credit_limit" => 10)
|
@@ -275,6 +285,18 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
|
275
285
|
assert_equal "is invalid", firm.errors.on("account")
|
276
286
|
end
|
277
287
|
|
288
|
+
|
289
|
+
def test_save_succeeds_for_invalid_has_one_with_validate_false
|
290
|
+
firm = Firm.find(:first)
|
291
|
+
assert firm.valid?
|
292
|
+
|
293
|
+
firm.unvalidated_account = Account.new
|
294
|
+
|
295
|
+
assert !firm.unvalidated_account.valid?
|
296
|
+
assert firm.valid?
|
297
|
+
assert firm.save
|
298
|
+
end
|
299
|
+
|
278
300
|
def test_assignment_before_either_saved
|
279
301
|
firm = Firm.new("name" => "GlobalMegaCorp")
|
280
302
|
firm.account = a = Account.new("credit_limit" => 1000)
|