activerecord 2.0.5 → 2.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 +168 -6
- data/README +27 -22
- data/RUNNING_UNIT_TESTS +7 -4
- data/Rakefile +22 -25
- data/lib/active_record.rb +8 -2
- data/lib/active_record/aggregations.rb +21 -12
- data/lib/active_record/association_preload.rb +277 -0
- data/lib/active_record/associations.rb +481 -295
- data/lib/active_record/associations/association_collection.rb +162 -37
- data/lib/active_record/associations/association_proxy.rb +71 -7
- data/lib/active_record/associations/belongs_to_association.rb +5 -3
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +5 -6
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +12 -64
- data/lib/active_record/associations/has_many_association.rb +8 -73
- data/lib/active_record/associations/has_many_through_association.rb +68 -117
- data/lib/active_record/associations/has_one_association.rb +7 -5
- data/lib/active_record/associations/has_one_through_association.rb +28 -0
- data/lib/active_record/attribute_methods.rb +69 -19
- data/lib/active_record/base.rb +496 -275
- data/lib/active_record/calculations.rb +28 -21
- data/lib/active_record/callbacks.rb +9 -38
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +3 -2
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +232 -45
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +141 -27
- data/lib/active_record/connection_adapters/abstract_adapter.rb +9 -13
- data/lib/active_record/connection_adapters/mysql_adapter.rb +57 -24
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +143 -42
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +18 -10
- data/lib/active_record/dirty.rb +158 -0
- data/lib/active_record/fixtures.rb +121 -156
- data/lib/active_record/locking/optimistic.rb +14 -11
- data/lib/active_record/locking/pessimistic.rb +2 -2
- data/lib/active_record/migration.rb +157 -77
- data/lib/active_record/named_scope.rb +163 -0
- data/lib/active_record/observer.rb +19 -5
- data/lib/active_record/reflection.rb +34 -14
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +4 -4
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/serializers/json_serializer.rb +37 -28
- data/lib/active_record/serializers/xml_serializer.rb +52 -29
- data/lib/active_record/test_case.rb +36 -0
- data/lib/active_record/timestamp.rb +4 -4
- data/lib/active_record/transactions.rb +3 -3
- data/lib/active_record/validations.rb +182 -248
- data/lib/active_record/version.rb +2 -2
- data/test/{fixtures → assets}/example.log +0 -0
- data/test/{fixtures → assets}/flowers.jpg +0 -0
- data/test/cases/aaa_create_tables_test.rb +24 -0
- data/test/cases/active_schema_test_mysql.rb +95 -0
- data/test/cases/active_schema_test_postgresql.rb +24 -0
- data/test/{adapter_test.rb → cases/adapter_test.rb} +15 -14
- data/test/{adapter_test_sqlserver.rb → cases/adapter_test_sqlserver.rb} +95 -95
- data/test/{aggregations_test.rb → cases/aggregations_test.rb} +20 -20
- data/test/{ar_schema_test.rb → cases/ar_schema_test.rb} +6 -6
- data/test/cases/associations/belongs_to_associations_test.rb +412 -0
- data/test/{associations → cases/associations}/callbacks_test.rb +24 -10
- data/test/{associations → cases/associations}/cascaded_eager_loading_test.rb +18 -17
- data/test/cases/associations/eager_load_nested_include_test.rb +83 -0
- data/test/{associations → cases/associations}/eager_singularization_test.rb +5 -5
- data/test/{associations → cases/associations}/eager_test.rb +216 -51
- data/test/{associations → cases/associations}/extension_test.rb +8 -8
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +684 -0
- data/test/cases/associations/has_many_associations_test.rb +932 -0
- data/test/cases/associations/has_many_through_associations_test.rb +190 -0
- data/test/cases/associations/has_one_associations_test.rb +323 -0
- data/test/cases/associations/has_one_through_associations_test.rb +74 -0
- data/test/{associations → cases/associations}/inner_join_association_test.rb +20 -20
- data/test/{associations → cases/associations}/join_model_test.rb +175 -35
- data/test/cases/associations_test.rb +262 -0
- data/test/{attribute_methods_test.rb → cases/attribute_methods_test.rb} +103 -11
- data/test/{base_test.rb → cases/base_test.rb} +338 -191
- data/test/{binary_test.rb → cases/binary_test.rb} +6 -4
- data/test/{calculations_test.rb → cases/calculations_test.rb} +35 -23
- data/test/{callbacks_test.rb → cases/callbacks_test.rb} +7 -7
- data/test/{class_inheritable_attributes_test.rb → cases/class_inheritable_attributes_test.rb} +3 -3
- data/test/{column_alias_test.rb → cases/column_alias_test.rb} +3 -3
- data/test/{connection_test_firebird.rb → cases/connection_test_firebird.rb} +2 -2
- data/test/{connection_test_mysql.rb → cases/connection_test_mysql.rb} +2 -2
- data/test/{copy_table_test_sqlite.rb → cases/copy_table_test_sqlite.rb} +13 -13
- data/test/{datatype_test_postgresql.rb → cases/datatype_test_postgresql.rb} +8 -8
- data/test/{date_time_test.rb → cases/date_time_test.rb} +5 -5
- data/test/{default_test_firebird.rb → cases/default_test_firebird.rb} +3 -3
- data/test/{defaults_test.rb → cases/defaults_test.rb} +8 -6
- data/test/{deprecated_finder_test.rb → cases/deprecated_finder_test.rb} +3 -3
- data/test/cases/dirty_test.rb +163 -0
- data/test/cases/finder_respond_to_test.rb +76 -0
- data/test/{finder_test.rb → cases/finder_test.rb} +266 -33
- data/test/{fixtures_test.rb → cases/fixtures_test.rb} +88 -72
- data/test/cases/helper.rb +47 -0
- data/test/{inheritance_test.rb → cases/inheritance_test.rb} +61 -17
- data/test/cases/invalid_date_test.rb +24 -0
- data/test/{json_serialization_test.rb → cases/json_serialization_test.rb} +36 -11
- data/test/{lifecycle_test.rb → cases/lifecycle_test.rb} +16 -13
- data/test/{locking_test.rb → cases/locking_test.rb} +17 -10
- data/test/{method_scoping_test.rb → cases/method_scoping_test.rb} +75 -39
- data/test/{migration_test.rb → cases/migration_test.rb} +420 -80
- data/test/{migration_test_firebird.rb → cases/migration_test_firebird.rb} +3 -3
- data/test/{mixin_test.rb → cases/mixin_test.rb} +7 -6
- data/test/{modules_test.rb → cases/modules_test.rb} +11 -6
- data/test/{multiple_db_test.rb → cases/multiple_db_test.rb} +5 -5
- data/test/cases/named_scope_test.rb +157 -0
- data/test/{pk_test.rb → cases/pk_test.rb} +10 -10
- data/test/{query_cache_test.rb → cases/query_cache_test.rb} +12 -10
- data/test/{readonly_test.rb → cases/readonly_test.rb} +11 -11
- data/test/{reflection_test.rb → cases/reflection_test.rb} +15 -14
- data/test/{reserved_word_test_mysql.rb → cases/reserved_word_test_mysql.rb} +4 -5
- data/test/{schema_authorization_test_postgresql.rb → cases/schema_authorization_test_postgresql.rb} +5 -5
- data/test/cases/schema_dumper_test.rb +138 -0
- data/test/cases/schema_test_postgresql.rb +102 -0
- data/test/{serialization_test.rb → cases/serialization_test.rb} +7 -7
- data/test/{synonym_test_oracle.rb → cases/synonym_test_oracle.rb} +5 -5
- data/test/{table_name_test_sqlserver.rb → cases/table_name_test_sqlserver.rb} +3 -3
- data/test/{threaded_connections_test.rb → cases/threaded_connections_test.rb} +7 -7
- data/test/{transactions_test.rb → cases/transactions_test.rb} +31 -5
- data/test/{unconnected_test.rb → cases/unconnected_test.rb} +2 -2
- data/test/{validations_test.rb → cases/validations_test.rb} +141 -39
- data/test/{xml_serialization_test.rb → cases/xml_serialization_test.rb} +12 -12
- data/test/config.rb +5 -0
- data/test/connections/native_db2/connection.rb +1 -1
- data/test/connections/native_firebird/connection.rb +1 -1
- data/test/connections/native_frontbase/connection.rb +1 -1
- data/test/connections/native_mysql/connection.rb +1 -1
- data/test/connections/native_openbase/connection.rb +1 -1
- data/test/connections/native_oracle/connection.rb +1 -1
- data/test/connections/native_postgresql/connection.rb +1 -3
- data/test/connections/native_sqlite/connection.rb +2 -2
- data/test/connections/native_sqlite3/connection.rb +2 -2
- data/test/connections/native_sqlite3/in_memory_connection.rb +3 -3
- data/test/connections/native_sybase/connection.rb +1 -1
- data/test/fixtures/author_addresses.yml +5 -0
- data/test/fixtures/authors.yml +2 -0
- data/test/fixtures/clubs.yml +6 -0
- data/test/fixtures/jobs.yml +7 -0
- data/test/fixtures/members.yml +4 -0
- data/test/fixtures/memberships.yml +20 -0
- data/test/fixtures/owners.yml +7 -0
- data/test/fixtures/people.yml +4 -1
- data/test/fixtures/pets.yml +14 -0
- data/test/fixtures/posts.yml +1 -0
- data/test/fixtures/price_estimates.yml +7 -0
- data/test/fixtures/readers.yml +5 -0
- data/test/fixtures/references.yml +17 -0
- data/test/fixtures/sponsors.yml +9 -0
- data/test/fixtures/subscribers.yml +7 -0
- data/test/fixtures/subscriptions.yml +12 -0
- data/test/fixtures/taggings.yml +4 -1
- data/test/fixtures/topics.yml +22 -2
- data/test/fixtures/warehouse-things.yml +3 -0
- data/test/{fixtures/migrations_with_decimal → migrations/decimal}/1_give_me_big_numbers.rb +0 -0
- data/test/{fixtures/migrations_with_duplicate → migrations/duplicate}/1_people_have_last_names.rb +1 -1
- data/test/{fixtures/migrations_with_duplicate → migrations/duplicate}/2_we_need_reminders.rb +1 -1
- data/test/{fixtures/migrations_with_duplicate → migrations/duplicate}/3_foo.rb +0 -0
- data/test/{fixtures/migrations → migrations/duplicate}/3_innocent_jointable.rb +0 -0
- data/test/migrations/duplicate_names/20080507052938_chunky.rb +7 -0
- data/test/migrations/duplicate_names/20080507053028_chunky.rb +7 -0
- data/test/{fixtures/migrations_with_duplicate → migrations/interleaved/pass_1}/3_innocent_jointable.rb +0 -0
- data/test/{fixtures/migrations → migrations/interleaved/pass_2}/1_people_have_last_names.rb +1 -1
- data/test/{fixtures/migrations_with_missing_versions/4_innocent_jointable.rb → migrations/interleaved/pass_2/3_innocent_jointable.rb} +0 -0
- data/test/{fixtures/migrations_with_missing_versions → migrations/interleaved/pass_3}/1_people_have_last_names.rb +1 -1
- data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +8 -0
- data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +12 -0
- data/test/{fixtures/migrations_with_missing_versions → migrations/missing}/1000_people_have_middle_names.rb +1 -1
- data/test/migrations/missing/1_people_have_last_names.rb +9 -0
- data/test/{fixtures/migrations_with_missing_versions → migrations/missing}/3_we_need_reminders.rb +1 -1
- data/test/migrations/missing/4_innocent_jointable.rb +12 -0
- data/test/migrations/valid/1_people_have_last_names.rb +9 -0
- data/test/{fixtures/migrations → migrations/valid}/2_we_need_reminders.rb +1 -1
- data/test/migrations/valid/3_innocent_jointable.rb +12 -0
- data/test/{fixtures → models}/author.rb +28 -4
- data/test/{fixtures → models}/auto_id.rb +0 -0
- data/test/{fixtures → models}/binary.rb +0 -0
- data/test/{fixtures → models}/book.rb +0 -0
- data/test/{fixtures → models}/categorization.rb +0 -0
- data/test/{fixtures → models}/category.rb +8 -5
- data/test/{fixtures → models}/citation.rb +0 -0
- data/test/models/club.rb +7 -0
- data/test/{fixtures → models}/column_name.rb +0 -0
- data/test/{fixtures → models}/comment.rb +5 -3
- data/test/{fixtures → models}/company.rb +15 -6
- data/test/{fixtures → models}/company_in_module.rb +5 -3
- data/test/{fixtures → models}/computer.rb +0 -1
- data/test/{fixtures → models}/contact.rb +1 -1
- data/test/{fixtures → models}/course.rb +0 -0
- data/test/{fixtures → models}/customer.rb +8 -8
- data/test/{fixtures → models}/default.rb +0 -0
- data/test/{fixtures → models}/developer.rb +14 -10
- data/test/{fixtures → models}/edge.rb +0 -0
- data/test/{fixtures → models}/entrant.rb +0 -0
- data/test/models/guid.rb +2 -0
- data/test/{fixtures → models}/item.rb +0 -0
- data/test/models/job.rb +5 -0
- data/test/{fixtures → models}/joke.rb +0 -0
- data/test/{fixtures → models}/keyboard.rb +0 -0
- data/test/{fixtures → models}/legacy_thing.rb +0 -0
- data/test/{fixtures → models}/matey.rb +0 -0
- data/test/models/member.rb +9 -0
- data/test/models/membership.rb +9 -0
- data/test/{fixtures → models}/minimalistic.rb +0 -0
- data/test/{fixtures → models}/mixed_case_monkey.rb +0 -0
- data/test/{fixtures → models}/movie.rb +0 -0
- data/test/{fixtures → models}/order.rb +2 -2
- data/test/models/owner.rb +4 -0
- data/test/{fixtures → models}/parrot.rb +0 -0
- data/test/models/person.rb +10 -0
- data/test/models/pet.rb +4 -0
- data/test/models/pirate.rb +9 -0
- data/test/{fixtures → models}/post.rb +23 -2
- data/test/models/price_estimate.rb +3 -0
- data/test/{fixtures → models}/project.rb +1 -0
- data/test/{fixtures → models}/reader.rb +0 -0
- data/test/models/reference.rb +4 -0
- data/test/{fixtures → models}/reply.rb +7 -5
- data/test/{fixtures → models}/ship.rb +0 -0
- data/test/models/sponsor.rb +4 -0
- data/test/{fixtures → models}/subject.rb +0 -0
- data/test/{fixtures → models}/subscriber.rb +2 -0
- data/test/models/subscription.rb +4 -0
- data/test/{fixtures → models}/tag.rb +0 -0
- data/test/{fixtures → models}/tagging.rb +0 -0
- data/test/{fixtures → models}/task.rb +0 -0
- data/test/{fixtures → models}/topic.rb +32 -4
- data/test/{fixtures → models}/treasure.rb +2 -0
- data/test/{fixtures → models}/vertex.rb +0 -0
- data/test/models/warehouse_thing.rb +5 -0
- data/test/schema/mysql_specific_schema.rb +12 -0
- data/test/schema/postgresql_specific_schema.rb +103 -0
- data/test/schema/schema.rb +421 -0
- data/test/schema/schema2.rb +6 -0
- data/test/schema/sqlite_specific_schema.rb +25 -0
- data/test/schema/sqlserver_specific_schema.rb +5 -0
- metadata +192 -176
- data/test/aaa_create_tables_test.rb +0 -72
- data/test/abstract_unit.rb +0 -84
- data/test/active_schema_test_mysql.rb +0 -46
- data/test/all.sh +0 -8
- data/test/association_inheritance_reload.rb +0 -14
- data/test/associations_test.rb +0 -2177
- data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +0 -1
- data/test/fixtures/bad_fixtures/attr_with_spaces +0 -1
- data/test/fixtures/bad_fixtures/blank_line +0 -3
- data/test/fixtures/bad_fixtures/duplicate_attributes +0 -3
- data/test/fixtures/bad_fixtures/missing_value +0 -1
- data/test/fixtures/db_definitions/db2.drop.sql +0 -33
- data/test/fixtures/db_definitions/db2.sql +0 -235
- data/test/fixtures/db_definitions/db22.drop.sql +0 -2
- data/test/fixtures/db_definitions/db22.sql +0 -5
- data/test/fixtures/db_definitions/firebird.drop.sql +0 -65
- data/test/fixtures/db_definitions/firebird.sql +0 -310
- data/test/fixtures/db_definitions/firebird2.drop.sql +0 -2
- data/test/fixtures/db_definitions/firebird2.sql +0 -6
- data/test/fixtures/db_definitions/frontbase.drop.sql +0 -33
- data/test/fixtures/db_definitions/frontbase.sql +0 -273
- data/test/fixtures/db_definitions/frontbase2.drop.sql +0 -1
- data/test/fixtures/db_definitions/frontbase2.sql +0 -4
- data/test/fixtures/db_definitions/openbase.drop.sql +0 -2
- data/test/fixtures/db_definitions/openbase.sql +0 -318
- data/test/fixtures/db_definitions/openbase2.drop.sql +0 -2
- data/test/fixtures/db_definitions/openbase2.sql +0 -7
- data/test/fixtures/db_definitions/oracle.drop.sql +0 -67
- data/test/fixtures/db_definitions/oracle.sql +0 -330
- data/test/fixtures/db_definitions/oracle2.drop.sql +0 -2
- data/test/fixtures/db_definitions/oracle2.sql +0 -6
- data/test/fixtures/db_definitions/postgresql.drop.sql +0 -44
- data/test/fixtures/db_definitions/postgresql.sql +0 -292
- data/test/fixtures/db_definitions/postgresql2.drop.sql +0 -2
- data/test/fixtures/db_definitions/postgresql2.sql +0 -4
- data/test/fixtures/db_definitions/schema.rb +0 -354
- data/test/fixtures/db_definitions/schema2.rb +0 -11
- data/test/fixtures/db_definitions/sqlite.drop.sql +0 -33
- data/test/fixtures/db_definitions/sqlite.sql +0 -219
- data/test/fixtures/db_definitions/sqlite2.drop.sql +0 -2
- data/test/fixtures/db_definitions/sqlite2.sql +0 -5
- data/test/fixtures/db_definitions/sybase.drop.sql +0 -35
- data/test/fixtures/db_definitions/sybase.sql +0 -222
- data/test/fixtures/db_definitions/sybase2.drop.sql +0 -4
- data/test/fixtures/db_definitions/sybase2.sql +0 -5
- data/test/fixtures/developers_projects/david_action_controller +0 -3
- data/test/fixtures/developers_projects/david_active_record +0 -3
- data/test/fixtures/developers_projects/jamis_active_record +0 -2
- data/test/fixtures/person.rb +0 -4
- data/test/fixtures/pirate.rb +0 -5
- data/test/fixtures/subscribers/first +0 -2
- data/test/fixtures/subscribers/second +0 -2
- data/test/schema_dumper_test.rb +0 -131
- data/test/schema_test_postgresql.rb +0 -64
@@ -0,0 +1,932 @@
|
|
1
|
+
require "cases/helper"
|
2
|
+
require 'models/developer'
|
3
|
+
require 'models/project'
|
4
|
+
require 'models/company'
|
5
|
+
require 'models/topic'
|
6
|
+
require 'models/reply'
|
7
|
+
require 'models/category'
|
8
|
+
require 'models/post'
|
9
|
+
require 'models/author'
|
10
|
+
require 'models/comment'
|
11
|
+
require 'models/person'
|
12
|
+
require 'models/reader'
|
13
|
+
|
14
|
+
class HasManyAssociationsTest < ActiveRecord::TestCase
|
15
|
+
fixtures :accounts, :categories, :companies, :developers, :projects,
|
16
|
+
:developers_projects, :topics, :authors, :comments, :author_addresses,
|
17
|
+
:people, :posts
|
18
|
+
|
19
|
+
def setup
|
20
|
+
Client.destroyed_client_ids.clear
|
21
|
+
end
|
22
|
+
|
23
|
+
def force_signal37_to_load_all_clients_of_firm
|
24
|
+
companies(:first_firm).clients_of_firm.each {|f| }
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_counting_with_counter_sql
|
28
|
+
assert_equal 2, Firm.find(:first).clients.count
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_counting
|
32
|
+
assert_equal 2, Firm.find(:first).plain_clients.count
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_counting_with_empty_hash_conditions
|
36
|
+
assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => {})
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_counting_with_single_conditions
|
40
|
+
assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_counting_with_single_hash
|
44
|
+
assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_counting_with_column_name_and_hash
|
48
|
+
assert_equal 2, Firm.find(:first).plain_clients.count(:all, :conditions => '1=1')
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_finding
|
52
|
+
assert_equal 2, Firm.find(:first).clients.length
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_find_with_blank_conditions
|
56
|
+
[[], {}, nil, ""].each do |blank|
|
57
|
+
assert_equal 2, Firm.find(:first).clients.find(:all, :conditions => blank).size
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_find_many_with_merged_options
|
62
|
+
assert_equal 1, companies(:first_firm).limited_clients.size
|
63
|
+
assert_equal 1, companies(:first_firm).limited_clients.find(:all).size
|
64
|
+
assert_equal 2, companies(:first_firm).limited_clients.find(:all, :limit => nil).size
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_dynamic_find_should_respect_association_order
|
68
|
+
assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find(:first, :conditions => "type = 'Client'")
|
69
|
+
assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client')
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_dynamic_find_order_should_override_association_order
|
73
|
+
assert_equal companies(:first_client), companies(:first_firm).clients_sorted_desc.find(:first, :conditions => "type = 'Client'", :order => 'id')
|
74
|
+
assert_equal companies(:first_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client', :order => 'id')
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_dynamic_find_all_should_respect_association_order
|
78
|
+
assert_equal [companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc.find(:all, :conditions => "type = 'Client'")
|
79
|
+
assert_equal [companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc.find_all_by_type('Client')
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_dynamic_find_all_order_should_override_association_order
|
83
|
+
assert_equal [companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc.find(:all, :conditions => "type = 'Client'", :order => 'id')
|
84
|
+
assert_equal [companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc.find_all_by_type('Client', :order => 'id')
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_dynamic_find_all_should_respect_association_limit
|
88
|
+
assert_equal 1, companies(:first_firm).limited_clients.find(:all, :conditions => "type = 'Client'").length
|
89
|
+
assert_equal 1, companies(:first_firm).limited_clients.find_all_by_type('Client').length
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_dynamic_find_all_limit_should_override_association_limit
|
93
|
+
assert_equal 2, companies(:first_firm).limited_clients.find(:all, :conditions => "type = 'Client'", :limit => 9_000).length
|
94
|
+
assert_equal 2, companies(:first_firm).limited_clients.find_all_by_type('Client', :limit => 9_000).length
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_dynamic_find_all_should_respect_readonly_access
|
98
|
+
companies(:first_firm).readonly_clients.find(:all).each { |c| assert_raise(ActiveRecord::ReadOnlyRecord) { c.save! } }
|
99
|
+
companies(:first_firm).readonly_clients.find(:all).each { |c| assert c.readonly? }
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_cant_save_has_many_readonly_association
|
103
|
+
authors(:david).readonly_comments.each { |c| assert_raise(ActiveRecord::ReadOnlyRecord) { c.save! } }
|
104
|
+
authors(:david).readonly_comments.each { |c| assert c.readonly? }
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_triple_equality
|
108
|
+
assert !(Array === Firm.find(:first).clients)
|
109
|
+
assert Firm.find(:first).clients === Array
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_finding_default_orders
|
113
|
+
assert_equal "Summit", Firm.find(:first).clients.first.name
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_finding_with_different_class_name_and_order
|
117
|
+
assert_equal "Microsoft", Firm.find(:first).clients_sorted_desc.first.name
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_finding_with_foreign_key
|
121
|
+
assert_equal "Microsoft", Firm.find(:first).clients_of_firm.first.name
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_finding_with_condition
|
125
|
+
assert_equal "Microsoft", Firm.find(:first).clients_like_ms.first.name
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_finding_with_condition_hash
|
129
|
+
assert_equal "Microsoft", Firm.find(:first).clients_like_ms_with_hash_conditions.first.name
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_finding_using_sql
|
133
|
+
firm = Firm.find(:first)
|
134
|
+
first_client = firm.clients_using_sql.first
|
135
|
+
assert_not_nil first_client
|
136
|
+
assert_equal "Microsoft", first_client.name
|
137
|
+
assert_equal 1, firm.clients_using_sql.size
|
138
|
+
assert_equal 1, Firm.find(:first).clients_using_sql.size
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_counting_using_sql
|
142
|
+
assert_equal 1, Firm.find(:first).clients_using_counter_sql.size
|
143
|
+
assert Firm.find(:first).clients_using_counter_sql.any?
|
144
|
+
assert_equal 0, Firm.find(:first).clients_using_zero_counter_sql.size
|
145
|
+
assert !Firm.find(:first).clients_using_zero_counter_sql.any?
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_counting_non_existant_items_using_sql
|
149
|
+
assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_belongs_to_sanity
|
153
|
+
c = Client.new
|
154
|
+
assert_nil c.firm
|
155
|
+
|
156
|
+
if c.firm
|
157
|
+
assert false, "belongs_to failed if check"
|
158
|
+
end
|
159
|
+
|
160
|
+
unless c.firm
|
161
|
+
else
|
162
|
+
assert false, "belongs_to failed unless check"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_find_ids
|
167
|
+
firm = Firm.find(:first)
|
168
|
+
|
169
|
+
assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find }
|
170
|
+
|
171
|
+
client = firm.clients.find(2)
|
172
|
+
assert_kind_of Client, client
|
173
|
+
|
174
|
+
client_ary = firm.clients.find([2])
|
175
|
+
assert_kind_of Array, client_ary
|
176
|
+
assert_equal client, client_ary.first
|
177
|
+
|
178
|
+
client_ary = firm.clients.find(2, 3)
|
179
|
+
assert_kind_of Array, client_ary
|
180
|
+
assert_equal 2, client_ary.size
|
181
|
+
assert_equal client, client_ary.first
|
182
|
+
|
183
|
+
assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find(2, 99) }
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_find_string_ids_when_using_finder_sql
|
187
|
+
firm = Firm.find(:first)
|
188
|
+
|
189
|
+
client = firm.clients_using_finder_sql.find("2")
|
190
|
+
assert_kind_of Client, client
|
191
|
+
|
192
|
+
client_ary = firm.clients_using_finder_sql.find(["2"])
|
193
|
+
assert_kind_of Array, client_ary
|
194
|
+
assert_equal client, client_ary.first
|
195
|
+
|
196
|
+
client_ary = firm.clients_using_finder_sql.find("2", "3")
|
197
|
+
assert_kind_of Array, client_ary
|
198
|
+
assert_equal 2, client_ary.size
|
199
|
+
assert client_ary.include?(client)
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_find_all
|
203
|
+
firm = Firm.find(:first)
|
204
|
+
assert_equal 2, firm.clients.find(:all, :conditions => "#{QUOTED_TYPE} = 'Client'").length
|
205
|
+
assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_find_all_sanitized
|
209
|
+
firm = Firm.find(:first)
|
210
|
+
summit = firm.clients.find(:all, :conditions => "name = 'Summit'")
|
211
|
+
assert_equal summit, firm.clients.find(:all, :conditions => ["name = ?", "Summit"])
|
212
|
+
assert_equal summit, firm.clients.find(:all, :conditions => ["name = :name", { :name => "Summit" }])
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_find_first
|
216
|
+
firm = Firm.find(:first)
|
217
|
+
client2 = Client.find(2)
|
218
|
+
assert_equal firm.clients.first, firm.clients.find(:first)
|
219
|
+
assert_equal client2, firm.clients.find(:first, :conditions => "#{QUOTED_TYPE} = 'Client'")
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_find_first_sanitized
|
223
|
+
firm = Firm.find(:first)
|
224
|
+
client2 = Client.find(2)
|
225
|
+
assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = ?", 'Client'])
|
226
|
+
assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }])
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_find_in_collection
|
230
|
+
assert_equal Client.find(2).name, companies(:first_firm).clients.find(2).name
|
231
|
+
assert_raises(ActiveRecord::RecordNotFound) { companies(:first_firm).clients.find(6) }
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_find_grouped
|
235
|
+
all_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1")
|
236
|
+
grouped_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1", :group => "firm_id", :select => 'firm_id, count(id) as clients_count')
|
237
|
+
assert_equal 2, all_clients_of_firm1.size
|
238
|
+
assert_equal 1, grouped_clients_of_firm1.size
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_adding
|
242
|
+
force_signal37_to_load_all_clients_of_firm
|
243
|
+
natural = Client.new("name" => "Natural Company")
|
244
|
+
companies(:first_firm).clients_of_firm << natural
|
245
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size # checking via the collection
|
246
|
+
assert_equal 2, companies(:first_firm).clients_of_firm(true).size # checking using the db
|
247
|
+
assert_equal natural, companies(:first_firm).clients_of_firm.last
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_adding_using_create
|
251
|
+
first_firm = companies(:first_firm)
|
252
|
+
assert_equal 2, first_firm.plain_clients.size
|
253
|
+
natural = first_firm.plain_clients.create(:name => "Natural Company")
|
254
|
+
assert_equal 3, first_firm.plain_clients.length
|
255
|
+
assert_equal 3, first_firm.plain_clients.size
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_create_with_bang_on_has_many_when_parent_is_new_raises
|
259
|
+
assert_raises(ActiveRecord::RecordNotSaved) do
|
260
|
+
firm = Firm.new
|
261
|
+
firm.plain_clients.create! :name=>"Whoever"
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_regular_create_on_has_many_when_parent_is_new_raises
|
266
|
+
assert_raises(ActiveRecord::RecordNotSaved) do
|
267
|
+
firm = Firm.new
|
268
|
+
firm.plain_clients.create :name=>"Whoever"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def test_create_with_bang_on_has_many_raises_when_record_not_saved
|
273
|
+
assert_raises(ActiveRecord::RecordInvalid) do
|
274
|
+
firm = Firm.find(:first)
|
275
|
+
firm.plain_clients.create!
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_create_with_bang_on_habtm_when_parent_is_new_raises
|
280
|
+
assert_raises(ActiveRecord::RecordNotSaved) do
|
281
|
+
Developer.new("name" => "Aredridel").projects.create!
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_adding_a_mismatch_class
|
286
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil }
|
287
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 }
|
288
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << Topic.find(1) }
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_adding_a_collection
|
292
|
+
force_signal37_to_load_all_clients_of_firm
|
293
|
+
companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
|
294
|
+
assert_equal 3, companies(:first_firm).clients_of_firm.size
|
295
|
+
assert_equal 3, companies(:first_firm).clients_of_firm(true).size
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_adding_before_save
|
299
|
+
no_of_firms = Firm.count
|
300
|
+
no_of_clients = Client.count
|
301
|
+
|
302
|
+
new_firm = Firm.new("name" => "A New Firm, Inc")
|
303
|
+
c = Client.new("name" => "Apple")
|
304
|
+
|
305
|
+
new_firm.clients_of_firm.push Client.new("name" => "Natural Company")
|
306
|
+
assert_equal 1, new_firm.clients_of_firm.size
|
307
|
+
new_firm.clients_of_firm << c
|
308
|
+
assert_equal 2, new_firm.clients_of_firm.size
|
309
|
+
|
310
|
+
assert_equal no_of_firms, Firm.count # Firm was not saved to database.
|
311
|
+
assert_equal no_of_clients, Client.count # Clients were not saved to database.
|
312
|
+
assert new_firm.save
|
313
|
+
assert !new_firm.new_record?
|
314
|
+
assert !c.new_record?
|
315
|
+
assert_equal new_firm, c.firm
|
316
|
+
assert_equal no_of_firms+1, Firm.count # Firm was saved to database.
|
317
|
+
assert_equal no_of_clients+2, Client.count # Clients were saved to database.
|
318
|
+
|
319
|
+
assert_equal 2, new_firm.clients_of_firm.size
|
320
|
+
assert_equal 2, new_firm.clients_of_firm(true).size
|
321
|
+
end
|
322
|
+
|
323
|
+
def test_invalid_adding
|
324
|
+
firm = Firm.find(1)
|
325
|
+
assert !(firm.clients_of_firm << c = Client.new)
|
326
|
+
assert c.new_record?
|
327
|
+
assert !firm.valid?
|
328
|
+
assert !firm.save
|
329
|
+
assert c.new_record?
|
330
|
+
end
|
331
|
+
|
332
|
+
def test_invalid_adding_before_save
|
333
|
+
no_of_firms = Firm.count
|
334
|
+
no_of_clients = Client.count
|
335
|
+
new_firm = Firm.new("name" => "A New Firm, Inc")
|
336
|
+
new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")])
|
337
|
+
assert c.new_record?
|
338
|
+
assert !c.valid?
|
339
|
+
assert !new_firm.valid?
|
340
|
+
assert !new_firm.save
|
341
|
+
assert c.new_record?
|
342
|
+
assert new_firm.new_record?
|
343
|
+
end
|
344
|
+
|
345
|
+
def test_build
|
346
|
+
company = companies(:first_firm)
|
347
|
+
new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
|
348
|
+
assert !company.clients_of_firm.loaded?
|
349
|
+
|
350
|
+
assert_equal "Another Client", new_client.name
|
351
|
+
assert new_client.new_record?
|
352
|
+
assert_equal new_client, company.clients_of_firm.last
|
353
|
+
company.name += '-changed'
|
354
|
+
assert_queries(2) { assert company.save }
|
355
|
+
assert !new_client.new_record?
|
356
|
+
assert_equal 2, company.clients_of_firm(true).size
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_build_many
|
360
|
+
company = companies(:first_firm)
|
361
|
+
new_clients = assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
|
362
|
+
|
363
|
+
assert_equal 2, new_clients.size
|
364
|
+
company.name += '-changed'
|
365
|
+
assert_queries(3) { assert company.save }
|
366
|
+
assert_equal 3, company.clients_of_firm(true).size
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_build_followed_by_save_does_not_load_target
|
370
|
+
new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client")
|
371
|
+
assert companies(:first_firm).save
|
372
|
+
assert !companies(:first_firm).clients_of_firm.loaded?
|
373
|
+
end
|
374
|
+
|
375
|
+
def test_build_without_loading_association
|
376
|
+
first_topic = topics(:first)
|
377
|
+
Reply.column_names
|
378
|
+
|
379
|
+
assert_equal 1, first_topic.replies.length
|
380
|
+
|
381
|
+
assert_no_queries do
|
382
|
+
first_topic.replies.build(:title => "Not saved", :content => "Superstars")
|
383
|
+
assert_equal 2, first_topic.replies.size
|
384
|
+
end
|
385
|
+
|
386
|
+
assert_equal 2, first_topic.replies.to_ary.size
|
387
|
+
end
|
388
|
+
|
389
|
+
def test_create_without_loading_association
|
390
|
+
first_firm = companies(:first_firm)
|
391
|
+
Firm.column_names
|
392
|
+
Client.column_names
|
393
|
+
|
394
|
+
assert_equal 1, first_firm.clients_of_firm.size
|
395
|
+
first_firm.clients_of_firm.reset
|
396
|
+
|
397
|
+
assert_queries(1) do
|
398
|
+
first_firm.clients_of_firm.create(:name => "Superstars")
|
399
|
+
end
|
400
|
+
|
401
|
+
assert_equal 2, first_firm.clients_of_firm.size
|
402
|
+
end
|
403
|
+
|
404
|
+
def test_invalid_build
|
405
|
+
new_client = companies(:first_firm).clients_of_firm.build
|
406
|
+
assert new_client.new_record?
|
407
|
+
assert !new_client.valid?
|
408
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm.last
|
409
|
+
assert !companies(:first_firm).save
|
410
|
+
assert new_client.new_record?
|
411
|
+
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
|
412
|
+
end
|
413
|
+
|
414
|
+
def test_create
|
415
|
+
force_signal37_to_load_all_clients_of_firm
|
416
|
+
new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
417
|
+
assert !new_client.new_record?
|
418
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm.last
|
419
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_create_many
|
423
|
+
companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
|
424
|
+
assert_equal 3, companies(:first_firm).clients_of_firm(true).size
|
425
|
+
end
|
426
|
+
|
427
|
+
def test_create_followed_by_save_does_not_load_target
|
428
|
+
new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
429
|
+
assert companies(:first_firm).save
|
430
|
+
assert !companies(:first_firm).clients_of_firm.loaded?
|
431
|
+
end
|
432
|
+
|
433
|
+
def test_find_or_initialize
|
434
|
+
the_client = companies(:first_firm).clients.find_or_initialize_by_name("Yet another client")
|
435
|
+
assert_equal companies(:first_firm).id, the_client.firm_id
|
436
|
+
assert_equal "Yet another client", the_client.name
|
437
|
+
assert the_client.new_record?
|
438
|
+
end
|
439
|
+
|
440
|
+
def test_find_or_create
|
441
|
+
number_of_clients = companies(:first_firm).clients.size
|
442
|
+
the_client = companies(:first_firm).clients.find_or_create_by_name("Yet another client")
|
443
|
+
assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
|
444
|
+
assert_equal the_client, companies(:first_firm).clients.find_or_create_by_name("Yet another client")
|
445
|
+
assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_deleting
|
449
|
+
force_signal37_to_load_all_clients_of_firm
|
450
|
+
companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first)
|
451
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
452
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
453
|
+
end
|
454
|
+
|
455
|
+
def test_deleting_before_save
|
456
|
+
new_firm = Firm.new("name" => "A New Firm, Inc.")
|
457
|
+
new_client = new_firm.clients_of_firm.build("name" => "Another Client")
|
458
|
+
assert_equal 1, new_firm.clients_of_firm.size
|
459
|
+
new_firm.clients_of_firm.delete(new_client)
|
460
|
+
assert_equal 0, new_firm.clients_of_firm.size
|
461
|
+
end
|
462
|
+
|
463
|
+
def test_deleting_a_collection
|
464
|
+
force_signal37_to_load_all_clients_of_firm
|
465
|
+
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
466
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size
|
467
|
+
companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]])
|
468
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
469
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
470
|
+
end
|
471
|
+
|
472
|
+
def test_delete_all
|
473
|
+
force_signal37_to_load_all_clients_of_firm
|
474
|
+
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
475
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size
|
476
|
+
companies(:first_firm).clients_of_firm.delete_all
|
477
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
478
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
479
|
+
end
|
480
|
+
|
481
|
+
def test_delete_all_with_not_yet_loaded_association_collection
|
482
|
+
force_signal37_to_load_all_clients_of_firm
|
483
|
+
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
484
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size
|
485
|
+
companies(:first_firm).clients_of_firm.reset
|
486
|
+
companies(:first_firm).clients_of_firm.delete_all
|
487
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
488
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
489
|
+
end
|
490
|
+
|
491
|
+
def test_clearing_an_association_collection
|
492
|
+
firm = companies(:first_firm)
|
493
|
+
client_id = firm.clients_of_firm.first.id
|
494
|
+
assert_equal 1, firm.clients_of_firm.size
|
495
|
+
|
496
|
+
firm.clients_of_firm.clear
|
497
|
+
|
498
|
+
assert_equal 0, firm.clients_of_firm.size
|
499
|
+
assert_equal 0, firm.clients_of_firm(true).size
|
500
|
+
assert_equal [], Client.destroyed_client_ids[firm.id]
|
501
|
+
|
502
|
+
# Should not be destroyed since the association is not dependent.
|
503
|
+
assert_nothing_raised do
|
504
|
+
assert Client.find(client_id).firm.nil?
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
def test_clearing_a_dependent_association_collection
|
509
|
+
firm = companies(:first_firm)
|
510
|
+
client_id = firm.dependent_clients_of_firm.first.id
|
511
|
+
assert_equal 1, firm.dependent_clients_of_firm.size
|
512
|
+
|
513
|
+
# :dependent means destroy is called on each client
|
514
|
+
firm.dependent_clients_of_firm.clear
|
515
|
+
|
516
|
+
assert_equal 0, firm.dependent_clients_of_firm.size
|
517
|
+
assert_equal 0, firm.dependent_clients_of_firm(true).size
|
518
|
+
assert_equal [client_id], Client.destroyed_client_ids[firm.id]
|
519
|
+
|
520
|
+
# Should be destroyed since the association is dependent.
|
521
|
+
assert Client.find_by_id(client_id).nil?
|
522
|
+
end
|
523
|
+
|
524
|
+
def test_clearing_an_exclusively_dependent_association_collection
|
525
|
+
firm = companies(:first_firm)
|
526
|
+
client_id = firm.exclusively_dependent_clients_of_firm.first.id
|
527
|
+
assert_equal 1, firm.exclusively_dependent_clients_of_firm.size
|
528
|
+
|
529
|
+
assert_equal [], Client.destroyed_client_ids[firm.id]
|
530
|
+
|
531
|
+
# :exclusively_dependent means each client is deleted directly from
|
532
|
+
# the database without looping through them calling destroy.
|
533
|
+
firm.exclusively_dependent_clients_of_firm.clear
|
534
|
+
|
535
|
+
assert_equal 0, firm.exclusively_dependent_clients_of_firm.size
|
536
|
+
assert_equal 0, firm.exclusively_dependent_clients_of_firm(true).size
|
537
|
+
# no destroy-filters should have been called
|
538
|
+
assert_equal [], Client.destroyed_client_ids[firm.id]
|
539
|
+
|
540
|
+
# Should be destroyed since the association is exclusively dependent.
|
541
|
+
assert Client.find_by_id(client_id).nil?
|
542
|
+
end
|
543
|
+
|
544
|
+
def test_dependent_association_respects_optional_conditions_on_delete
|
545
|
+
firm = companies(:odegy)
|
546
|
+
Client.create(:client_of => firm.id, :name => "BigShot Inc.")
|
547
|
+
Client.create(:client_of => firm.id, :name => "SmallTime Inc.")
|
548
|
+
# only one of two clients is included in the association due to the :conditions key
|
549
|
+
assert_equal 2, Client.find_all_by_client_of(firm.id).size
|
550
|
+
assert_equal 1, firm.dependent_conditional_clients_of_firm.size
|
551
|
+
firm.destroy
|
552
|
+
# only the correctly associated client should have been deleted
|
553
|
+
assert_equal 1, Client.find_all_by_client_of(firm.id).size
|
554
|
+
end
|
555
|
+
|
556
|
+
def test_dependent_association_respects_optional_sanitized_conditions_on_delete
|
557
|
+
firm = companies(:odegy)
|
558
|
+
Client.create(:client_of => firm.id, :name => "BigShot Inc.")
|
559
|
+
Client.create(:client_of => firm.id, :name => "SmallTime Inc.")
|
560
|
+
# only one of two clients is included in the association due to the :conditions key
|
561
|
+
assert_equal 2, Client.find_all_by_client_of(firm.id).size
|
562
|
+
assert_equal 1, firm.dependent_sanitized_conditional_clients_of_firm.size
|
563
|
+
firm.destroy
|
564
|
+
# only the correctly associated client should have been deleted
|
565
|
+
assert_equal 1, Client.find_all_by_client_of(firm.id).size
|
566
|
+
end
|
567
|
+
|
568
|
+
def test_creation_respects_hash_condition
|
569
|
+
ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.build
|
570
|
+
|
571
|
+
assert ms_client.save
|
572
|
+
assert_equal 'Microsoft', ms_client.name
|
573
|
+
|
574
|
+
another_ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.create
|
575
|
+
|
576
|
+
assert !another_ms_client.new_record?
|
577
|
+
assert_equal 'Microsoft', another_ms_client.name
|
578
|
+
end
|
579
|
+
|
580
|
+
def test_dependent_delete_and_destroy_with_belongs_to
|
581
|
+
author_address = author_addresses(:david_address)
|
582
|
+
assert_equal [], AuthorAddress.destroyed_author_address_ids[authors(:david).id]
|
583
|
+
|
584
|
+
assert_difference "AuthorAddress.count", -2 do
|
585
|
+
authors(:david).destroy
|
586
|
+
end
|
587
|
+
|
588
|
+
assert_equal [author_address.id], AuthorAddress.destroyed_author_address_ids[authors(:david).id]
|
589
|
+
end
|
590
|
+
|
591
|
+
def test_invalid_belongs_to_dependent_option_raises_exception
|
592
|
+
assert_raises ArgumentError do
|
593
|
+
Author.belongs_to :special_author_address, :dependent => :nullify
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
def test_clearing_without_initial_access
|
598
|
+
firm = companies(:first_firm)
|
599
|
+
|
600
|
+
firm.clients_of_firm.clear
|
601
|
+
|
602
|
+
assert_equal 0, firm.clients_of_firm.size
|
603
|
+
assert_equal 0, firm.clients_of_firm(true).size
|
604
|
+
end
|
605
|
+
|
606
|
+
def test_deleting_a_item_which_is_not_in_the_collection
|
607
|
+
force_signal37_to_load_all_clients_of_firm
|
608
|
+
summit = Client.find_by_name('Summit')
|
609
|
+
companies(:first_firm).clients_of_firm.delete(summit)
|
610
|
+
assert_equal 1, companies(:first_firm).clients_of_firm.size
|
611
|
+
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
|
612
|
+
assert_equal 2, summit.client_of
|
613
|
+
end
|
614
|
+
|
615
|
+
def test_deleting_type_mismatch
|
616
|
+
david = Developer.find(1)
|
617
|
+
david.projects.reload
|
618
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(1) }
|
619
|
+
end
|
620
|
+
|
621
|
+
def test_deleting_self_type_mismatch
|
622
|
+
david = Developer.find(1)
|
623
|
+
david.projects.reload
|
624
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(Project.find(1).developers) }
|
625
|
+
end
|
626
|
+
|
627
|
+
def test_destroy_all
|
628
|
+
force_signal37_to_load_all_clients_of_firm
|
629
|
+
assert !companies(:first_firm).clients_of_firm.empty?, "37signals has clients after load"
|
630
|
+
companies(:first_firm).clients_of_firm.destroy_all
|
631
|
+
assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all"
|
632
|
+
assert companies(:first_firm).clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh"
|
633
|
+
end
|
634
|
+
|
635
|
+
def test_dependence
|
636
|
+
firm = companies(:first_firm)
|
637
|
+
assert_equal 2, firm.clients.size
|
638
|
+
firm.destroy
|
639
|
+
assert Client.find(:all, :conditions => "firm_id=#{firm.id}").empty?
|
640
|
+
end
|
641
|
+
|
642
|
+
def test_destroy_dependent_when_deleted_from_association
|
643
|
+
firm = Firm.find(:first)
|
644
|
+
assert_equal 2, firm.clients.size
|
645
|
+
|
646
|
+
client = firm.clients.first
|
647
|
+
firm.clients.delete(client)
|
648
|
+
|
649
|
+
assert_raise(ActiveRecord::RecordNotFound) { Client.find(client.id) }
|
650
|
+
assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(client.id) }
|
651
|
+
assert_equal 1, firm.clients.size
|
652
|
+
end
|
653
|
+
|
654
|
+
def test_three_levels_of_dependence
|
655
|
+
topic = Topic.create "title" => "neat and simple"
|
656
|
+
reply = topic.replies.create "title" => "neat and simple", "content" => "still digging it"
|
657
|
+
silly_reply = reply.replies.create "title" => "neat and simple", "content" => "ain't complaining"
|
658
|
+
|
659
|
+
assert_nothing_raised { topic.destroy }
|
660
|
+
end
|
661
|
+
|
662
|
+
uses_transaction :test_dependence_with_transaction_support_on_failure
|
663
|
+
def test_dependence_with_transaction_support_on_failure
|
664
|
+
firm = companies(:first_firm)
|
665
|
+
clients = firm.clients
|
666
|
+
assert_equal 2, clients.length
|
667
|
+
clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end }
|
668
|
+
|
669
|
+
firm.destroy rescue "do nothing"
|
670
|
+
|
671
|
+
assert_equal 2, Client.find(:all, :conditions => "firm_id=#{firm.id}").size
|
672
|
+
end
|
673
|
+
|
674
|
+
def test_dependence_on_account
|
675
|
+
num_accounts = Account.count
|
676
|
+
companies(:first_firm).destroy
|
677
|
+
assert_equal num_accounts - 1, Account.count
|
678
|
+
end
|
679
|
+
|
680
|
+
def test_depends_and_nullify
|
681
|
+
num_accounts = Account.count
|
682
|
+
num_companies = Company.count
|
683
|
+
|
684
|
+
core = companies(:rails_core)
|
685
|
+
assert_equal accounts(:rails_core_account), core.account
|
686
|
+
assert_equal companies(:leetsoft, :jadedpixel), core.companies
|
687
|
+
core.destroy
|
688
|
+
assert_nil accounts(:rails_core_account).reload.firm_id
|
689
|
+
assert_nil companies(:leetsoft).reload.client_of
|
690
|
+
assert_nil companies(:jadedpixel).reload.client_of
|
691
|
+
|
692
|
+
|
693
|
+
assert_equal num_accounts, Account.count
|
694
|
+
end
|
695
|
+
|
696
|
+
def test_included_in_collection
|
697
|
+
assert companies(:first_firm).clients.include?(Client.find(2))
|
698
|
+
end
|
699
|
+
|
700
|
+
def test_adding_array_and_collection
|
701
|
+
assert_nothing_raised { Firm.find(:first).clients + Firm.find(:all).last.clients }
|
702
|
+
end
|
703
|
+
|
704
|
+
def test_find_all_without_conditions
|
705
|
+
firm = companies(:first_firm)
|
706
|
+
assert_equal 2, firm.clients.find(:all).length
|
707
|
+
end
|
708
|
+
|
709
|
+
def test_replace_with_less
|
710
|
+
firm = Firm.find(:first)
|
711
|
+
firm.clients = [companies(:first_client)]
|
712
|
+
assert firm.save, "Could not save firm"
|
713
|
+
firm.reload
|
714
|
+
assert_equal 1, firm.clients.length
|
715
|
+
end
|
716
|
+
|
717
|
+
def test_replace_with_less_and_dependent_nullify
|
718
|
+
num_companies = Company.count
|
719
|
+
companies(:rails_core).companies = []
|
720
|
+
assert_equal num_companies, Company.count
|
721
|
+
end
|
722
|
+
|
723
|
+
def test_replace_with_new
|
724
|
+
firm = Firm.find(:first)
|
725
|
+
firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
|
726
|
+
firm.save
|
727
|
+
firm.reload
|
728
|
+
assert_equal 2, firm.clients.length
|
729
|
+
assert !firm.clients.include?(:first_client)
|
730
|
+
end
|
731
|
+
|
732
|
+
def test_replace_on_new_object
|
733
|
+
firm = Firm.new("name" => "New Firm")
|
734
|
+
firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
|
735
|
+
assert firm.save
|
736
|
+
firm.reload
|
737
|
+
assert_equal 2, firm.clients.length
|
738
|
+
assert firm.clients.include?(Client.find_by_name("New Client"))
|
739
|
+
end
|
740
|
+
|
741
|
+
def test_get_ids
|
742
|
+
assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
|
743
|
+
end
|
744
|
+
|
745
|
+
def test_assign_ids
|
746
|
+
firm = Firm.new("name" => "Apple")
|
747
|
+
firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
|
748
|
+
firm.save
|
749
|
+
firm.reload
|
750
|
+
assert_equal 2, firm.clients.length
|
751
|
+
assert firm.clients.include?(companies(:second_client))
|
752
|
+
end
|
753
|
+
|
754
|
+
def test_assign_ids_ignoring_blanks
|
755
|
+
firm = Firm.create!(:name => 'Apple')
|
756
|
+
firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id, '']
|
757
|
+
firm.save!
|
758
|
+
|
759
|
+
assert_equal 2, firm.clients(true).size
|
760
|
+
assert firm.clients.include?(companies(:second_client))
|
761
|
+
end
|
762
|
+
|
763
|
+
def test_get_ids_for_through
|
764
|
+
assert_equal [comments(:eager_other_comment1).id], authors(:mary).comment_ids
|
765
|
+
end
|
766
|
+
|
767
|
+
def test_modifying_a_through_a_has_many_should_raise
|
768
|
+
[
|
769
|
+
lambda { authors(:mary).comment_ids = [comments(:greetings).id, comments(:more_greetings).id] },
|
770
|
+
lambda { authors(:mary).comments = [comments(:greetings), comments(:more_greetings)] },
|
771
|
+
lambda { authors(:mary).comments << Comment.create!(:body => "Yay", :post_id => 424242) },
|
772
|
+
lambda { authors(:mary).comments.delete(authors(:mary).comments.first) },
|
773
|
+
].each {|block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasManyReflection, &block) }
|
774
|
+
end
|
775
|
+
|
776
|
+
|
777
|
+
def test_assign_ids_for_through_a_belongs_to
|
778
|
+
post = Post.new(:title => "Assigning IDs works!", :body => "You heared it here first, folks!")
|
779
|
+
post.person_ids = [people(:david).id, people(:michael).id]
|
780
|
+
post.save
|
781
|
+
post.reload
|
782
|
+
assert_equal 2, post.people.length
|
783
|
+
assert post.people.include?(people(:david))
|
784
|
+
end
|
785
|
+
|
786
|
+
def test_dynamic_find_should_respect_association_order_for_through
|
787
|
+
assert_equal Comment.find(10), authors(:david).comments_desc.find(:first, :conditions => "comments.type = 'SpecialComment'")
|
788
|
+
assert_equal Comment.find(10), authors(:david).comments_desc.find_by_type('SpecialComment')
|
789
|
+
end
|
790
|
+
|
791
|
+
def test_dynamic_find_order_should_override_association_order_for_through
|
792
|
+
assert_equal Comment.find(3), authors(:david).comments_desc.find(:first, :conditions => "comments.type = 'SpecialComment'", :order => 'comments.id')
|
793
|
+
assert_equal Comment.find(3), authors(:david).comments_desc.find_by_type('SpecialComment', :order => 'comments.id')
|
794
|
+
end
|
795
|
+
|
796
|
+
def test_dynamic_find_all_should_respect_association_order_for_through
|
797
|
+
assert_equal [Comment.find(10), Comment.find(7), Comment.find(6), Comment.find(3)], authors(:david).comments_desc.find(:all, :conditions => "comments.type = 'SpecialComment'")
|
798
|
+
assert_equal [Comment.find(10), Comment.find(7), Comment.find(6), Comment.find(3)], authors(:david).comments_desc.find_all_by_type('SpecialComment')
|
799
|
+
end
|
800
|
+
|
801
|
+
def test_dynamic_find_all_order_should_override_association_order_for_through
|
802
|
+
assert_equal [Comment.find(3), Comment.find(6), Comment.find(7), Comment.find(10)], authors(:david).comments_desc.find(:all, :conditions => "comments.type = 'SpecialComment'", :order => 'comments.id')
|
803
|
+
assert_equal [Comment.find(3), Comment.find(6), Comment.find(7), Comment.find(10)], authors(:david).comments_desc.find_all_by_type('SpecialComment', :order => 'comments.id')
|
804
|
+
end
|
805
|
+
|
806
|
+
def test_dynamic_find_all_should_respect_association_limit_for_through
|
807
|
+
assert_equal 1, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'").length
|
808
|
+
assert_equal 1, authors(:david).limited_comments.find_all_by_type('SpecialComment').length
|
809
|
+
end
|
810
|
+
|
811
|
+
def test_dynamic_find_all_order_should_override_association_limit_for_through
|
812
|
+
assert_equal 4, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'", :limit => 9_000).length
|
813
|
+
assert_equal 4, authors(:david).limited_comments.find_all_by_type('SpecialComment', :limit => 9_000).length
|
814
|
+
end
|
815
|
+
|
816
|
+
def test_find_all_include_over_the_same_table_for_through
|
817
|
+
assert_equal 2, people(:michael).posts.find(:all, :include => :people).length
|
818
|
+
end
|
819
|
+
|
820
|
+
def test_has_many_through_respects_hash_conditions
|
821
|
+
assert_equal authors(:david).hello_posts, authors(:david).hello_posts_with_hash_conditions
|
822
|
+
assert_equal authors(:david).hello_post_comments, authors(:david).hello_post_comments_with_hash_conditions
|
823
|
+
end
|
824
|
+
|
825
|
+
def test_include_uses_array_include_after_loaded
|
826
|
+
firm = companies(:first_firm)
|
827
|
+
firm.clients.class # force load target
|
828
|
+
|
829
|
+
client = firm.clients.first
|
830
|
+
|
831
|
+
assert_no_queries do
|
832
|
+
assert firm.clients.loaded?
|
833
|
+
assert firm.clients.include?(client)
|
834
|
+
end
|
835
|
+
end
|
836
|
+
|
837
|
+
def test_include_checks_if_record_exists_if_target_not_loaded
|
838
|
+
firm = companies(:first_firm)
|
839
|
+
client = firm.clients.first
|
840
|
+
|
841
|
+
firm.reload
|
842
|
+
assert ! firm.clients.loaded?
|
843
|
+
assert_queries(1) do
|
844
|
+
assert firm.clients.include?(client)
|
845
|
+
end
|
846
|
+
assert ! firm.clients.loaded?
|
847
|
+
end
|
848
|
+
|
849
|
+
def test_include_loads_collection_if_target_uses_finder_sql
|
850
|
+
firm = companies(:first_firm)
|
851
|
+
client = firm.clients_using_sql.first
|
852
|
+
|
853
|
+
firm.reload
|
854
|
+
assert ! firm.clients_using_sql.loaded?
|
855
|
+
assert firm.clients_using_sql.include?(client)
|
856
|
+
assert firm.clients_using_sql.loaded?
|
857
|
+
end
|
858
|
+
|
859
|
+
|
860
|
+
def test_include_returns_false_for_non_matching_record_to_verify_scoping
|
861
|
+
firm = companies(:first_firm)
|
862
|
+
client = Client.create!(:name => 'Not Associated')
|
863
|
+
|
864
|
+
assert ! firm.clients.loaded?
|
865
|
+
assert ! firm.clients.include?(client)
|
866
|
+
end
|
867
|
+
|
868
|
+
def test_calling_first_or_last_on_association_should_not_load_association
|
869
|
+
firm = companies(:first_firm)
|
870
|
+
firm.clients.first
|
871
|
+
firm.clients.last
|
872
|
+
assert !firm.clients.loaded?
|
873
|
+
end
|
874
|
+
|
875
|
+
def test_calling_first_or_last_on_loaded_association_should_not_fetch_with_query
|
876
|
+
firm = companies(:first_firm)
|
877
|
+
firm.clients.class # force load target
|
878
|
+
assert firm.clients.loaded?
|
879
|
+
|
880
|
+
assert_no_queries do
|
881
|
+
firm.clients.first
|
882
|
+
assert_equal 2, firm.clients.first(2).size
|
883
|
+
firm.clients.last
|
884
|
+
assert_equal 2, firm.clients.last(2).size
|
885
|
+
end
|
886
|
+
end
|
887
|
+
|
888
|
+
def test_calling_first_or_last_on_existing_record_with_build_should_load_association
|
889
|
+
firm = companies(:first_firm)
|
890
|
+
firm.clients.build(:name => 'Foo')
|
891
|
+
assert !firm.clients.loaded?
|
892
|
+
|
893
|
+
assert_queries 1 do
|
894
|
+
firm.clients.first
|
895
|
+
firm.clients.last
|
896
|
+
end
|
897
|
+
|
898
|
+
assert firm.clients.loaded?
|
899
|
+
end
|
900
|
+
|
901
|
+
def test_calling_first_or_last_on_new_record_should_not_run_queries
|
902
|
+
firm = Firm.new
|
903
|
+
|
904
|
+
assert_no_queries do
|
905
|
+
firm.clients.first
|
906
|
+
firm.clients.last
|
907
|
+
end
|
908
|
+
end
|
909
|
+
|
910
|
+
def test_calling_first_or_last_with_find_options_on_loaded_association_should_fetch_with_query
|
911
|
+
firm = companies(:first_firm)
|
912
|
+
firm.clients.class # force load target
|
913
|
+
|
914
|
+
assert_queries 2 do
|
915
|
+
assert firm.clients.loaded?
|
916
|
+
firm.clients.first(:order => 'name')
|
917
|
+
firm.clients.last(:order => 'name')
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
def test_calling_first_or_last_with_integer_on_association_should_load_association
|
922
|
+
firm = companies(:first_firm)
|
923
|
+
|
924
|
+
assert_queries 1 do
|
925
|
+
firm.clients.first(2)
|
926
|
+
firm.clients.last(2)
|
927
|
+
end
|
928
|
+
|
929
|
+
assert firm.clients.loaded?
|
930
|
+
end
|
931
|
+
|
932
|
+
end
|