activerecord 1.0.0 → 2.0.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 +4928 -3
- data/README +45 -46
- data/RUNNING_UNIT_TESTS +8 -11
- data/Rakefile +247 -0
- data/install.rb +8 -38
- data/lib/active_record/aggregations.rb +64 -49
- data/lib/active_record/associations/association_collection.rb +217 -47
- data/lib/active_record/associations/association_proxy.rb +159 -0
- data/lib/active_record/associations/belongs_to_association.rb +56 -0
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +155 -37
- data/lib/active_record/associations/has_many_association.rb +145 -75
- data/lib/active_record/associations/has_many_through_association.rb +283 -0
- data/lib/active_record/associations/has_one_association.rb +96 -0
- data/lib/active_record/associations.rb +1537 -304
- data/lib/active_record/attribute_methods.rb +328 -0
- data/lib/active_record/base.rb +2001 -588
- data/lib/active_record/calculations.rb +269 -0
- data/lib/active_record/callbacks.rb +169 -165
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +308 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +171 -0
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +87 -0
- data/lib/active_record/connection_adapters/abstract/quoting.rb +69 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +472 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +306 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +125 -279
- data/lib/active_record/connection_adapters/mysql_adapter.rb +442 -77
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +805 -135
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -0
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +353 -69
- data/lib/active_record/fixtures.rb +946 -100
- data/lib/active_record/locking/optimistic.rb +144 -0
- data/lib/active_record/locking/pessimistic.rb +77 -0
- data/lib/active_record/migration.rb +417 -0
- data/lib/active_record/observer.rb +142 -32
- data/lib/active_record/query_cache.rb +23 -0
- data/lib/active_record/reflection.rb +163 -70
- data/lib/active_record/schema.rb +58 -0
- data/lib/active_record/schema_dumper.rb +171 -0
- data/lib/active_record/serialization.rb +98 -0
- data/lib/active_record/serializers/json_serializer.rb +71 -0
- data/lib/active_record/serializers/xml_serializer.rb +315 -0
- data/lib/active_record/timestamp.rb +41 -0
- data/lib/active_record/transactions.rb +87 -57
- data/lib/active_record/validations.rb +909 -122
- data/lib/active_record/vendor/db2.rb +362 -0
- data/lib/active_record/vendor/mysql.rb +126 -29
- data/lib/active_record/version.rb +9 -0
- data/lib/active_record.rb +35 -7
- data/lib/activerecord.rb +1 -0
- data/test/aaa_create_tables_test.rb +72 -0
- data/test/abstract_unit.rb +73 -5
- data/test/active_schema_test_mysql.rb +43 -0
- data/test/adapter_test.rb +105 -0
- data/test/adapter_test_sqlserver.rb +95 -0
- data/test/aggregations_test.rb +110 -16
- data/test/all.sh +2 -2
- data/test/ar_schema_test.rb +33 -0
- data/test/association_inheritance_reload.rb +14 -0
- data/test/associations/ar_joins_test.rb +0 -0
- data/test/associations/callbacks_test.rb +147 -0
- data/test/associations/cascaded_eager_loading_test.rb +110 -0
- data/test/associations/eager_singularization_test.rb +145 -0
- data/test/associations/eager_test.rb +442 -0
- data/test/associations/extension_test.rb +47 -0
- data/test/associations/inner_join_association_test.rb +88 -0
- data/test/associations/join_model_test.rb +553 -0
- data/test/associations_test.rb +1930 -267
- data/test/attribute_methods_test.rb +146 -0
- data/test/base_test.rb +1316 -84
- data/test/binary_test.rb +32 -0
- data/test/calculations_test.rb +251 -0
- data/test/callbacks_test.rb +400 -0
- data/test/class_inheritable_attributes_test.rb +3 -4
- data/test/column_alias_test.rb +17 -0
- data/test/connection_test_firebird.rb +8 -0
- data/test/connection_test_mysql.rb +30 -0
- data/test/connections/native_db2/connection.rb +25 -0
- data/test/connections/native_firebird/connection.rb +26 -0
- data/test/connections/native_frontbase/connection.rb +27 -0
- data/test/connections/native_mysql/connection.rb +21 -18
- data/test/connections/native_openbase/connection.rb +21 -0
- data/test/connections/native_oracle/connection.rb +27 -0
- data/test/connections/native_postgresql/connection.rb +17 -18
- data/test/connections/native_sqlite/connection.rb +17 -16
- data/test/connections/native_sqlite3/connection.rb +25 -0
- data/test/connections/native_sqlite3/in_memory_connection.rb +18 -0
- data/test/connections/native_sybase/connection.rb +23 -0
- data/test/copy_table_test_sqlite.rb +69 -0
- data/test/datatype_test_postgresql.rb +203 -0
- data/test/date_time_test.rb +37 -0
- data/test/default_test_firebird.rb +16 -0
- data/test/defaults_test.rb +67 -0
- data/test/deprecated_finder_test.rb +30 -0
- data/test/finder_test.rb +607 -32
- data/test/fixtures/accounts.yml +28 -0
- data/test/fixtures/all/developers.yml +0 -0
- data/test/fixtures/all/people.csv +0 -0
- data/test/fixtures/all/tasks.yml +0 -0
- data/test/fixtures/author.rb +107 -0
- data/test/fixtures/author_favorites.yml +4 -0
- data/test/fixtures/authors.yml +7 -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/binaries.yml +132 -0
- data/test/fixtures/binary.rb +2 -0
- data/test/fixtures/book.rb +4 -0
- data/test/fixtures/books.yml +7 -0
- data/test/fixtures/categories/special_categories.yml +9 -0
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
- data/test/fixtures/categories.yml +14 -0
- data/test/fixtures/categories_ordered.yml +7 -0
- data/test/fixtures/categories_posts.yml +23 -0
- data/test/fixtures/categorization.rb +5 -0
- data/test/fixtures/categorizations.yml +17 -0
- data/test/fixtures/category.rb +26 -0
- data/test/fixtures/citation.rb +6 -0
- data/test/fixtures/comment.rb +23 -0
- data/test/fixtures/comments.yml +59 -0
- data/test/fixtures/companies.yml +55 -0
- data/test/fixtures/company.rb +81 -4
- data/test/fixtures/company_in_module.rb +32 -6
- data/test/fixtures/computer.rb +4 -0
- data/test/fixtures/computers.yml +4 -0
- data/test/fixtures/contact.rb +16 -0
- data/test/fixtures/courses.yml +7 -0
- data/test/fixtures/customer.rb +28 -3
- data/test/fixtures/customers.yml +17 -0
- data/test/fixtures/db_definitions/db2.drop.sql +33 -0
- data/test/fixtures/db_definitions/db2.sql +235 -0
- data/test/fixtures/db_definitions/db22.drop.sql +2 -0
- data/test/fixtures/db_definitions/db22.sql +5 -0
- data/test/fixtures/db_definitions/firebird.drop.sql +65 -0
- data/test/fixtures/db_definitions/firebird.sql +310 -0
- data/test/fixtures/db_definitions/firebird2.drop.sql +2 -0
- data/test/fixtures/db_definitions/firebird2.sql +6 -0
- data/test/fixtures/db_definitions/frontbase.drop.sql +33 -0
- data/test/fixtures/db_definitions/frontbase.sql +273 -0
- data/test/fixtures/db_definitions/frontbase2.drop.sql +1 -0
- data/test/fixtures/db_definitions/frontbase2.sql +4 -0
- data/test/fixtures/db_definitions/openbase.drop.sql +2 -0
- data/test/fixtures/db_definitions/openbase.sql +318 -0
- data/test/fixtures/db_definitions/openbase2.drop.sql +2 -0
- data/test/fixtures/db_definitions/openbase2.sql +7 -0
- data/test/fixtures/db_definitions/oracle.drop.sql +67 -0
- data/test/fixtures/db_definitions/oracle.sql +330 -0
- data/test/fixtures/db_definitions/oracle2.drop.sql +2 -0
- data/test/fixtures/db_definitions/oracle2.sql +6 -0
- data/test/fixtures/db_definitions/postgresql.drop.sql +44 -0
- data/test/fixtures/db_definitions/postgresql.sql +217 -38
- data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/postgresql2.sql +2 -2
- data/test/fixtures/db_definitions/schema.rb +354 -0
- data/test/fixtures/db_definitions/schema2.rb +11 -0
- data/test/fixtures/db_definitions/sqlite.drop.sql +33 -0
- data/test/fixtures/db_definitions/sqlite.sql +139 -5
- data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlite2.sql +1 -0
- data/test/fixtures/db_definitions/sybase.drop.sql +35 -0
- data/test/fixtures/db_definitions/sybase.sql +222 -0
- data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
- data/test/fixtures/db_definitions/sybase2.sql +5 -0
- data/test/fixtures/developer.rb +70 -6
- data/test/fixtures/developers.yml +21 -0
- data/test/fixtures/developers_projects/david_action_controller +2 -1
- data/test/fixtures/developers_projects/david_active_record +2 -1
- data/test/fixtures/developers_projects.yml +17 -0
- data/test/fixtures/edge.rb +5 -0
- data/test/fixtures/edges.yml +6 -0
- data/test/fixtures/entrants.yml +14 -0
- data/test/fixtures/example.log +1 -0
- data/test/fixtures/fk_test_has_fk.yml +3 -0
- data/test/fixtures/fk_test_has_pk.yml +2 -0
- data/test/fixtures/flowers.jpg +0 -0
- data/test/fixtures/funny_jokes.yml +10 -0
- data/test/fixtures/item.rb +7 -0
- data/test/fixtures/items.yml +4 -0
- data/test/fixtures/joke.rb +3 -0
- data/test/fixtures/keyboard.rb +3 -0
- data/test/fixtures/legacy_thing.rb +3 -0
- data/test/fixtures/legacy_things.yml +3 -0
- data/test/fixtures/matey.rb +4 -0
- data/test/fixtures/mateys.yml +4 -0
- data/test/fixtures/migrations/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations/2_we_need_reminders.rb +12 -0
- data/test/fixtures/migrations/3_innocent_jointable.rb +12 -0
- data/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb +15 -0
- data/test/fixtures/migrations_with_duplicate/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations_with_duplicate/2_we_need_reminders.rb +12 -0
- data/test/fixtures/migrations_with_duplicate/3_foo.rb +7 -0
- data/test/fixtures/migrations_with_duplicate/3_innocent_jointable.rb +12 -0
- data/test/fixtures/migrations_with_missing_versions/1000_people_have_middle_names.rb +9 -0
- data/test/fixtures/migrations_with_missing_versions/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations_with_missing_versions/3_we_need_reminders.rb +12 -0
- data/test/fixtures/migrations_with_missing_versions/4_innocent_jointable.rb +12 -0
- data/test/fixtures/minimalistic.rb +2 -0
- data/test/fixtures/minimalistics.yml +2 -0
- data/test/fixtures/mixed_case_monkey.rb +3 -0
- data/test/fixtures/mixed_case_monkeys.yml +6 -0
- data/test/fixtures/mixins.yml +29 -0
- data/test/fixtures/movies.yml +7 -0
- data/test/fixtures/naked/csv/accounts.csv +1 -0
- data/test/fixtures/naked/yml/accounts.yml +1 -0
- data/test/fixtures/naked/yml/companies.yml +1 -0
- data/test/fixtures/naked/yml/courses.yml +1 -0
- data/test/fixtures/order.rb +4 -0
- data/test/fixtures/parrot.rb +13 -0
- data/test/fixtures/parrots.yml +27 -0
- data/test/fixtures/parrots_pirates.yml +7 -0
- data/test/fixtures/people.yml +3 -0
- data/test/fixtures/person.rb +4 -0
- data/test/fixtures/pirate.rb +5 -0
- data/test/fixtures/pirates.yml +9 -0
- data/test/fixtures/post.rb +59 -0
- data/test/fixtures/posts.yml +48 -0
- data/test/fixtures/project.rb +27 -2
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/reader.rb +4 -0
- data/test/fixtures/readers.yml +4 -0
- data/test/fixtures/reply.rb +18 -2
- data/test/fixtures/reserved_words/distinct.yml +5 -0
- data/test/fixtures/reserved_words/distincts_selects.yml +11 -0
- data/test/fixtures/reserved_words/group.yml +14 -0
- data/test/fixtures/reserved_words/select.yml +8 -0
- data/test/fixtures/reserved_words/values.yml +7 -0
- data/test/fixtures/ship.rb +3 -0
- data/test/fixtures/ships.yml +5 -0
- data/test/fixtures/subject.rb +4 -0
- data/test/fixtures/subscriber.rb +4 -3
- data/test/fixtures/tag.rb +7 -0
- data/test/fixtures/tagging.rb +10 -0
- data/test/fixtures/taggings.yml +25 -0
- data/test/fixtures/tags.yml +7 -0
- data/test/fixtures/task.rb +3 -0
- data/test/fixtures/tasks.yml +7 -0
- data/test/fixtures/topic.rb +20 -3
- data/test/fixtures/topics.yml +22 -0
- data/test/fixtures/treasure.rb +4 -0
- data/test/fixtures/treasures.yml +10 -0
- data/test/fixtures/vertex.rb +9 -0
- data/test/fixtures/vertices.yml +4 -0
- data/test/fixtures_test.rb +574 -8
- data/test/inheritance_test.rb +113 -27
- data/test/json_serialization_test.rb +180 -0
- data/test/lifecycle_test.rb +56 -29
- data/test/locking_test.rb +273 -0
- data/test/method_scoping_test.rb +416 -0
- data/test/migration_test.rb +933 -0
- data/test/migration_test_firebird.rb +124 -0
- data/test/mixin_test.rb +95 -0
- data/test/modules_test.rb +23 -10
- data/test/multiple_db_test.rb +17 -3
- data/test/pk_test.rb +59 -15
- data/test/query_cache_test.rb +104 -0
- data/test/readonly_test.rb +107 -0
- data/test/reflection_test.rb +124 -27
- data/test/reserved_word_test_mysql.rb +177 -0
- data/test/schema_authorization_test_postgresql.rb +75 -0
- data/test/schema_dumper_test.rb +131 -0
- data/test/schema_test_postgresql.rb +64 -0
- data/test/serialization_test.rb +47 -0
- data/test/synonym_test_oracle.rb +17 -0
- data/test/table_name_test_sqlserver.rb +23 -0
- data/test/threaded_connections_test.rb +48 -0
- data/test/transactions_test.rb +227 -29
- data/test/unconnected_test.rb +14 -6
- data/test/validations_test.rb +1293 -32
- data/test/xml_serialization_test.rb +202 -0
- metadata +347 -143
- data/dev-utils/eval_debugger.rb +0 -9
- data/examples/associations.rb +0 -87
- data/examples/shared_setup.rb +0 -15
- data/examples/validation.rb +0 -88
- data/lib/active_record/deprecated_associations.rb +0 -70
- data/lib/active_record/support/class_attribute_accessors.rb +0 -43
- data/lib/active_record/support/class_inheritable_attributes.rb +0 -37
- data/lib/active_record/support/clean_logger.rb +0 -10
- data/lib/active_record/support/inflector.rb +0 -70
- data/lib/active_record/vendor/simple.rb +0 -702
- data/lib/active_record/wrappers/yaml_wrapper.rb +0 -15
- data/lib/active_record/wrappings.rb +0 -59
- data/rakefile +0 -122
- data/test/deprecated_associations_test.rb +0 -336
- data/test/fixtures/accounts/signals37 +0 -3
- data/test/fixtures/accounts/unknown +0 -2
- data/test/fixtures/companies/first_client +0 -6
- data/test/fixtures/companies/first_firm +0 -4
- data/test/fixtures/companies/second_client +0 -6
- data/test/fixtures/courses/java +0 -2
- data/test/fixtures/courses/ruby +0 -2
- data/test/fixtures/customers/david +0 -6
- data/test/fixtures/db_definitions/mysql.sql +0 -96
- data/test/fixtures/db_definitions/mysql2.sql +0 -4
- data/test/fixtures/developers/david +0 -2
- data/test/fixtures/developers/jamis +0 -2
- data/test/fixtures/entrants/first +0 -3
- data/test/fixtures/entrants/second +0 -3
- data/test/fixtures/entrants/third +0 -3
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/movies/first +0 -2
- data/test/fixtures/movies/second +0 -2
- data/test/fixtures/projects/action_controller +0 -2
- data/test/fixtures/projects/active_record +0 -2
- data/test/fixtures/topics/first +0 -9
- data/test/fixtures/topics/second +0 -8
- data/test/inflector_test.rb +0 -104
- data/test/thread_safety_test.rb +0 -33
data/test/associations_test.rb
CHANGED
@@ -1,40 +1,51 @@
|
|
1
1
|
require 'abstract_unit'
|
2
2
|
require 'fixtures/developer'
|
3
3
|
require 'fixtures/project'
|
4
|
-
# require File.dirname(__FILE__) + '/../dev-utils/eval_debugger'
|
5
4
|
require 'fixtures/company'
|
6
5
|
require 'fixtures/topic'
|
7
6
|
require 'fixtures/reply'
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
require 'fixtures/computer'
|
8
|
+
require 'fixtures/customer'
|
9
|
+
require 'fixtures/order'
|
10
|
+
require 'fixtures/categorization'
|
11
|
+
require 'fixtures/category'
|
12
|
+
require 'fixtures/post'
|
13
|
+
require 'fixtures/author'
|
14
|
+
require 'fixtures/comment'
|
15
|
+
require 'fixtures/tag'
|
16
|
+
require 'fixtures/tagging'
|
17
|
+
require 'fixtures/person'
|
18
|
+
require 'fixtures/reader'
|
18
19
|
|
19
20
|
class AssociationsTest < Test::Unit::TestCase
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
fixtures :accounts, :companies, :developers, :projects, :developers_projects,
|
22
|
+
:computers
|
23
|
+
|
24
|
+
def test_bad_collection_keys
|
25
|
+
assert_raise(ArgumentError, 'ActiveRecord should have barked on bad collection keys') do
|
26
|
+
Class.new(ActiveRecord::Base).has_many(:wheels, :name => 'wheels')
|
27
|
+
end
|
23
28
|
end
|
24
29
|
|
30
|
+
def test_should_construct_new_finder_sql_after_create
|
31
|
+
person = Person.new
|
32
|
+
assert_equal [], person.readers.find(:all)
|
33
|
+
person.save!
|
34
|
+
reader = Reader.create! :person => person, :post => Post.new(:title => "foo", :body => "bar")
|
35
|
+
assert_equal [reader], person.readers.find(:all)
|
36
|
+
end
|
37
|
+
|
25
38
|
def test_force_reload
|
26
|
-
firm = Firm.new
|
39
|
+
firm = Firm.new("name" => "A New Firm, Inc")
|
27
40
|
firm.save
|
28
41
|
firm.clients.each {|c|} # forcing to load all clients
|
29
42
|
assert firm.clients.empty?, "New firm shouldn't have client objects"
|
30
|
-
assert !firm.has_clients?, "New firm shouldn't have clients"
|
31
43
|
assert_equal 0, firm.clients.size, "New firm should have 0 clients"
|
32
44
|
|
33
|
-
client = Client.new("firm_id" => firm.id)
|
45
|
+
client = Client.new("name" => "TheClient.com", "firm_id" => firm.id)
|
34
46
|
client.save
|
35
47
|
|
36
48
|
assert firm.clients.empty?, "New firm should have cached no client objects"
|
37
|
-
assert !firm.has_clients?, "New firm should have cached a no-clients response"
|
38
49
|
assert_equal 0, firm.clients.size, "New firm should have cached 0 clients count"
|
39
50
|
|
40
51
|
assert !firm.clients(true).empty?, "New firm should have reloaded client objects"
|
@@ -42,7 +53,8 @@ class AssociationsTest < Test::Unit::TestCase
|
|
42
53
|
end
|
43
54
|
|
44
55
|
def test_storing_in_pstore
|
45
|
-
|
56
|
+
require "tmpdir"
|
57
|
+
store_filename = File.join(Dir.tmpdir, "ar-pstore-association-test")
|
46
58
|
File.delete(store_filename) if File.exists?(store_filename)
|
47
59
|
require "pstore"
|
48
60
|
apple = Firm.create("name" => "Apple")
|
@@ -61,26 +73,120 @@ class AssociationsTest < Test::Unit::TestCase
|
|
61
73
|
end
|
62
74
|
end
|
63
75
|
|
76
|
+
class AssociationProxyTest < Test::Unit::TestCase
|
77
|
+
fixtures :authors, :posts, :categorizations, :categories, :developers, :projects, :developers_projects
|
78
|
+
|
79
|
+
def test_proxy_accessors
|
80
|
+
welcome = posts(:welcome)
|
81
|
+
assert_equal welcome, welcome.author.proxy_owner
|
82
|
+
assert_equal welcome.class.reflect_on_association(:author), welcome.author.proxy_reflection
|
83
|
+
welcome.author.class # force load target
|
84
|
+
assert_equal welcome.author, welcome.author.proxy_target
|
85
|
+
|
86
|
+
david = authors(:david)
|
87
|
+
assert_equal david, david.posts.proxy_owner
|
88
|
+
assert_equal david.class.reflect_on_association(:posts), david.posts.proxy_reflection
|
89
|
+
david.posts.first # force load target
|
90
|
+
assert_equal david.posts, david.posts.proxy_target
|
91
|
+
|
92
|
+
assert_equal david, david.posts_with_extension.testing_proxy_owner
|
93
|
+
assert_equal david.class.reflect_on_association(:posts_with_extension), david.posts_with_extension.testing_proxy_reflection
|
94
|
+
david.posts_with_extension.first # force load target
|
95
|
+
assert_equal david.posts_with_extension, david.posts_with_extension.testing_proxy_target
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_push_does_not_load_target
|
99
|
+
david = authors(:david)
|
100
|
+
|
101
|
+
david.categories << categories(:technology)
|
102
|
+
assert !david.categories.loaded?
|
103
|
+
assert david.categories.include?(categories(:technology))
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_push_does_not_lose_additions_to_new_record
|
107
|
+
josh = Author.new(:name => "Josh")
|
108
|
+
josh.posts << Post.new(:title => "New on Edge", :body => "More cool stuff!")
|
109
|
+
assert josh.posts.loaded?
|
110
|
+
assert_equal 1, josh.posts.size
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_save_on_parent_does_not_load_target
|
114
|
+
david = developers(:david)
|
115
|
+
|
116
|
+
assert !david.projects.loaded?
|
117
|
+
david.update_attribute(:created_at, Time.now)
|
118
|
+
assert !david.projects.loaded?
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_save_on_parent_saves_children
|
122
|
+
developer = Developer.create :name => "Bryan", :salary => 50_000
|
123
|
+
assert_equal 1, developer.reload.audit_logs.size
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_failed_reload_returns_nil
|
127
|
+
p = setup_dangling_association
|
128
|
+
assert_nil p.author.reload
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_failed_reset_returns_nil
|
132
|
+
p = setup_dangling_association
|
133
|
+
assert_nil p.author.reset
|
134
|
+
end
|
135
|
+
|
136
|
+
def setup_dangling_association
|
137
|
+
josh = Author.create(:name => "Josh")
|
138
|
+
p = Post.create(:title => "New on Edge", :body => "More cool stuff!", :author => josh)
|
139
|
+
josh.destroy
|
140
|
+
p
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
64
144
|
class HasOneAssociationsTest < Test::Unit::TestCase
|
145
|
+
fixtures :accounts, :companies, :developers, :projects, :developers_projects
|
146
|
+
|
65
147
|
def setup
|
66
|
-
|
67
|
-
@signals37 = Firm.find(1)
|
148
|
+
Account.destroyed_account_ids.clear
|
68
149
|
end
|
69
|
-
|
150
|
+
|
70
151
|
def test_has_one
|
71
|
-
assert_equal
|
72
|
-
assert_equal Account.find(1).credit_limit,
|
73
|
-
|
74
|
-
|
75
|
-
|
152
|
+
assert_equal companies(:first_firm).account, Account.find(1)
|
153
|
+
assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_has_one_cache_nils
|
157
|
+
firm = companies(:another_firm)
|
158
|
+
assert_queries(1) { assert_nil firm.account }
|
159
|
+
assert_queries(0) { assert_nil firm.account }
|
160
|
+
|
161
|
+
firms = Firm.find(:all, :include => :account)
|
162
|
+
assert_queries(0) { firms.each(&:account) }
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_can_marshal_has_one_association_with_nil_target
|
166
|
+
firm = Firm.new
|
167
|
+
assert_nothing_raised do
|
168
|
+
assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
|
169
|
+
end
|
170
|
+
|
171
|
+
firm.account
|
172
|
+
assert_nothing_raised do
|
173
|
+
assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
|
174
|
+
end
|
175
|
+
end
|
76
176
|
|
77
|
-
|
78
|
-
|
177
|
+
def test_proxy_assignment
|
178
|
+
company = companies(:first_firm)
|
179
|
+
assert_nothing_raised { company.account = company.account }
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_triple_equality
|
183
|
+
assert Account === companies(:first_firm).account
|
184
|
+
assert companies(:first_firm).account === Account
|
79
185
|
end
|
80
186
|
|
81
187
|
def test_type_mismatch
|
82
|
-
assert_raises(ActiveRecord::AssociationTypeMismatch) {
|
83
|
-
assert_raises(ActiveRecord::AssociationTypeMismatch) {
|
188
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 }
|
189
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) }
|
84
190
|
end
|
85
191
|
|
86
192
|
def test_natural_assignment
|
@@ -89,19 +195,81 @@ class HasOneAssociationsTest < Test::Unit::TestCase
|
|
89
195
|
apple.account = citibank
|
90
196
|
assert_equal apple.id, citibank.firm_id
|
91
197
|
end
|
92
|
-
|
198
|
+
|
93
199
|
def test_natural_assignment_to_nil
|
94
|
-
old_account_id =
|
95
|
-
|
96
|
-
|
97
|
-
assert_nil
|
98
|
-
|
200
|
+
old_account_id = companies(:first_firm).account.id
|
201
|
+
companies(:first_firm).account = nil
|
202
|
+
companies(:first_firm).save
|
203
|
+
assert_nil companies(:first_firm).account
|
204
|
+
# account is dependent, therefore is destroyed when reference to owner is lost
|
205
|
+
assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
|
99
206
|
end
|
100
207
|
|
101
|
-
def
|
208
|
+
def test_assignment_without_replacement
|
209
|
+
apple = Firm.create("name" => "Apple")
|
210
|
+
citibank = Account.create("credit_limit" => 10)
|
211
|
+
apple.account = citibank
|
212
|
+
assert_equal apple.id, citibank.firm_id
|
213
|
+
|
214
|
+
hsbc = apple.build_account({ :credit_limit => 20}, false)
|
215
|
+
assert_equal apple.id, hsbc.firm_id
|
216
|
+
hsbc.save
|
217
|
+
assert_equal apple.id, citibank.firm_id
|
218
|
+
|
219
|
+
nykredit = apple.create_account({ :credit_limit => 30}, false)
|
220
|
+
assert_equal apple.id, nykredit.firm_id
|
221
|
+
assert_equal apple.id, citibank.firm_id
|
222
|
+
assert_equal apple.id, hsbc.firm_id
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_assignment_without_replacement_on_create
|
226
|
+
apple = Firm.create("name" => "Apple")
|
227
|
+
citibank = Account.create("credit_limit" => 10)
|
228
|
+
apple.account = citibank
|
229
|
+
assert_equal apple.id, citibank.firm_id
|
230
|
+
|
231
|
+
hsbc = apple.create_account({:credit_limit => 10}, false)
|
232
|
+
assert_equal apple.id, hsbc.firm_id
|
233
|
+
hsbc.save
|
234
|
+
assert_equal apple.id, citibank.firm_id
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_dependence
|
238
|
+
num_accounts = Account.count
|
239
|
+
|
240
|
+
firm = Firm.find(1)
|
241
|
+
assert !firm.account.nil?
|
242
|
+
account_id = firm.account.id
|
243
|
+
assert_equal [], Account.destroyed_account_ids[firm.id]
|
244
|
+
|
245
|
+
firm.destroy
|
246
|
+
assert_equal num_accounts - 1, Account.count
|
247
|
+
assert_equal [account_id], Account.destroyed_account_ids[firm.id]
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_exclusive_dependence
|
251
|
+
num_accounts = Account.count
|
252
|
+
|
253
|
+
firm = ExclusivelyDependentFirm.find(9)
|
254
|
+
assert !firm.account.nil?
|
255
|
+
account_id = firm.account.id
|
256
|
+
assert_equal [], Account.destroyed_account_ids[firm.id]
|
257
|
+
|
258
|
+
firm.destroy
|
259
|
+
assert_equal num_accounts - 1, Account.count
|
260
|
+
assert_equal [], Account.destroyed_account_ids[firm.id]
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_dependence_with_nil_associate
|
264
|
+
firm = DependentFirm.new(:name => 'nullify')
|
265
|
+
firm.save!
|
266
|
+
assert_nothing_raised { firm.destroy }
|
267
|
+
end
|
268
|
+
|
269
|
+
def test_succesful_build_association
|
102
270
|
firm = Firm.new("name" => "GlobalMegaCorp")
|
103
271
|
firm.save
|
104
|
-
|
272
|
+
|
105
273
|
account = firm.build_account("credit_limit" => 1000)
|
106
274
|
assert account.save
|
107
275
|
assert_equal account, firm.account
|
@@ -110,291 +278,1290 @@ class HasOneAssociationsTest < Test::Unit::TestCase
|
|
110
278
|
def test_failing_build_association
|
111
279
|
firm = Firm.new("name" => "GlobalMegaCorp")
|
112
280
|
firm.save
|
113
|
-
|
281
|
+
|
114
282
|
account = firm.build_account
|
115
283
|
assert !account.save
|
116
284
|
assert_equal "can't be empty", account.errors.on("credit_limit")
|
117
285
|
end
|
118
286
|
|
119
|
-
def
|
287
|
+
def test_build_association_twice_without_saving_affects_nothing
|
288
|
+
count_of_account = Account.count
|
289
|
+
firm = Firm.find(:first)
|
290
|
+
account1 = firm.build_account("credit_limit" => 1000)
|
291
|
+
account2 = firm.build_account("credit_limit" => 2000)
|
292
|
+
|
293
|
+
assert_equal count_of_account, Account.count
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_create_association
|
297
|
+
firm = Firm.create(:name => "GlobalMegaCorp")
|
298
|
+
account = firm.create_account(:credit_limit => 1000)
|
299
|
+
assert_equal account, firm.reload.account
|
300
|
+
end
|
301
|
+
|
302
|
+
def test_build
|
120
303
|
firm = Firm.new("name" => "GlobalMegaCorp")
|
121
304
|
firm.save
|
122
|
-
|
305
|
+
|
306
|
+
firm.account = account = Account.new("credit_limit" => 1000)
|
307
|
+
assert_equal account, firm.account
|
308
|
+
assert account.save
|
309
|
+
assert_equal account, firm.account
|
123
310
|
end
|
124
|
-
|
125
|
-
def
|
311
|
+
|
312
|
+
def test_build_before_child_saved
|
126
313
|
firm = Firm.find(1)
|
127
|
-
assert !firm.account.nil?
|
128
|
-
firm.destroy
|
129
|
-
assert_equal 1, Account.find_all.length
|
130
|
-
end
|
131
314
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
assert
|
136
|
-
firm.
|
315
|
+
account = firm.account.build("credit_limit" => 1000)
|
316
|
+
assert_equal account, firm.account
|
317
|
+
assert account.new_record?
|
318
|
+
assert firm.save
|
319
|
+
assert_equal account, firm.account
|
320
|
+
assert !account.new_record?
|
137
321
|
end
|
138
|
-
end
|
139
322
|
|
323
|
+
def test_build_before_either_saved
|
324
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
140
325
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
326
|
+
firm.account = account = Account.new("credit_limit" => 1000)
|
327
|
+
assert_equal account, firm.account
|
328
|
+
assert account.new_record?
|
329
|
+
assert firm.save
|
330
|
+
assert_equal account, firm.account
|
331
|
+
assert !account.new_record?
|
145
332
|
end
|
146
|
-
|
147
|
-
def
|
148
|
-
|
333
|
+
|
334
|
+
def test_failing_build_association
|
335
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
336
|
+
firm.save
|
337
|
+
|
338
|
+
firm.account = account = Account.new
|
339
|
+
assert_equal account, firm.account
|
340
|
+
assert !account.save
|
341
|
+
assert_equal account, firm.account
|
342
|
+
assert_equal "can't be empty", account.errors.on("credit_limit")
|
149
343
|
end
|
150
|
-
|
151
|
-
def
|
152
|
-
|
344
|
+
|
345
|
+
def test_create
|
346
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
347
|
+
firm.save
|
348
|
+
firm.account = account = Account.create("credit_limit" => 1000)
|
349
|
+
assert_equal account, firm.account
|
153
350
|
end
|
154
351
|
|
155
|
-
def
|
156
|
-
|
352
|
+
def test_create_before_save
|
353
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
354
|
+
firm.account = account = Account.create("credit_limit" => 1000)
|
355
|
+
assert_equal account, firm.account
|
157
356
|
end
|
158
357
|
|
159
|
-
def
|
160
|
-
|
358
|
+
def test_dependence_with_missing_association
|
359
|
+
Account.destroy_all
|
360
|
+
firm = Firm.find(1)
|
361
|
+
assert firm.account.nil?
|
362
|
+
firm.destroy
|
161
363
|
end
|
162
364
|
|
163
|
-
def
|
164
|
-
|
365
|
+
def test_dependence_with_missing_association_and_nullify
|
366
|
+
Account.destroy_all
|
367
|
+
firm = DependentFirm.find(:first)
|
368
|
+
assert firm.account.nil?
|
369
|
+
firm.destroy
|
165
370
|
end
|
166
371
|
|
167
|
-
def
|
168
|
-
|
372
|
+
def test_assignment_before_parent_saved
|
373
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
374
|
+
firm.account = a = Account.find(1)
|
375
|
+
assert firm.new_record?
|
376
|
+
assert_equal a, firm.account
|
377
|
+
assert firm.save
|
378
|
+
assert_equal a, firm.account
|
379
|
+
assert_equal a, firm.account(true)
|
169
380
|
end
|
170
381
|
|
171
|
-
def
|
172
|
-
firm = Firm.
|
173
|
-
firm.
|
174
|
-
|
175
|
-
|
176
|
-
assert_equal
|
382
|
+
def test_finding_with_interpolated_condition
|
383
|
+
firm = Firm.find(:first)
|
384
|
+
superior = firm.clients.create(:name => 'SuperiorCo')
|
385
|
+
superior.rating = 10
|
386
|
+
superior.save
|
387
|
+
assert_equal 10, firm.clients_with_interpolated_conditions.first.rating
|
177
388
|
end
|
178
389
|
|
179
|
-
def
|
180
|
-
|
181
|
-
|
390
|
+
def test_assignment_before_child_saved
|
391
|
+
firm = Firm.find(1)
|
392
|
+
firm.account = a = Account.new("credit_limit" => 1000)
|
393
|
+
assert !a.new_record?
|
394
|
+
assert_equal a, firm.account
|
395
|
+
assert_equal a, firm.account
|
396
|
+
assert_equal a, firm.account(true)
|
182
397
|
end
|
183
398
|
|
184
|
-
def
|
185
|
-
|
186
|
-
|
187
|
-
|
399
|
+
def test_assignment_before_either_saved
|
400
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
401
|
+
firm.account = a = Account.new("credit_limit" => 1000)
|
402
|
+
assert firm.new_record?
|
403
|
+
assert a.new_record?
|
404
|
+
assert_equal a, firm.account
|
405
|
+
assert firm.save
|
406
|
+
assert !firm.new_record?
|
407
|
+
assert !a.new_record?
|
408
|
+
assert_equal a, firm.account
|
409
|
+
assert_equal a, firm.account(true)
|
188
410
|
end
|
189
411
|
|
190
|
-
def
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
412
|
+
def test_not_resaved_when_unchanged
|
413
|
+
firm = Firm.find(:first, :include => :account)
|
414
|
+
assert_queries(1) { firm.save! }
|
415
|
+
|
416
|
+
firm = Firm.find(:first)
|
417
|
+
firm.account = Account.find(:first)
|
418
|
+
assert_queries(1) { firm.save! }
|
419
|
+
|
420
|
+
firm = Firm.find(:first).clone
|
421
|
+
firm.account = Account.find(:first)
|
422
|
+
assert_queries(2) { firm.save! }
|
423
|
+
|
424
|
+
firm = Firm.find(:first).clone
|
425
|
+
firm.account = Account.find(:first).clone
|
426
|
+
assert_queries(2) { firm.save! }
|
197
427
|
end
|
198
|
-
|
199
|
-
def
|
200
|
-
|
201
|
-
|
202
|
-
|
428
|
+
|
429
|
+
def test_save_still_works_after_accessing_nil_has_one
|
430
|
+
jp = Company.new :name => 'Jaded Pixel'
|
431
|
+
jp.dummy_account.nil?
|
432
|
+
|
433
|
+
assert_nothing_raised do
|
434
|
+
jp.save!
|
435
|
+
end
|
203
436
|
end
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
437
|
+
|
438
|
+
end
|
439
|
+
|
440
|
+
|
441
|
+
class HasManyAssociationsTest < Test::Unit::TestCase
|
442
|
+
fixtures :accounts, :companies, :developers, :projects,
|
443
|
+
:developers_projects, :topics, :authors, :comments
|
444
|
+
|
445
|
+
def setup
|
446
|
+
Client.destroyed_client_ids.clear
|
210
447
|
end
|
211
448
|
|
212
|
-
def
|
213
|
-
|
214
|
-
assert_equal "Another Client", new_client.name
|
215
|
-
assert new_client.save
|
216
|
-
assert_equal 2, @signals37.clients_of_firm(true).size
|
449
|
+
def force_signal37_to_load_all_clients_of_firm
|
450
|
+
companies(:first_firm).clients_of_firm.each {|f| }
|
217
451
|
end
|
218
|
-
|
219
|
-
def
|
220
|
-
|
221
|
-
new_client = @signals37.clients_of_firm.create("name" => "Another Client")
|
222
|
-
assert_equal new_client, @signals37.clients_of_firm.last
|
223
|
-
assert_equal new_client, @signals37.clients_of_firm(true).last
|
452
|
+
|
453
|
+
def test_counting_with_counter_sql
|
454
|
+
assert_equal 2, Firm.find(:first).clients.count
|
224
455
|
end
|
225
456
|
|
226
|
-
def
|
227
|
-
|
228
|
-
@signals37.clients_of_firm.delete(@signals37.clients_of_firm.first)
|
229
|
-
assert_equal 0, @signals37.clients_of_firm.size
|
230
|
-
assert_equal 0, @signals37.clients_of_firm(true).size
|
457
|
+
def test_counting
|
458
|
+
assert_equal 2, Firm.find(:first).plain_clients.count
|
231
459
|
end
|
232
460
|
|
233
|
-
def
|
234
|
-
|
235
|
-
@signals37.clients_of_firm.create("name" => "Another Client")
|
236
|
-
assert_equal 2, @signals37.clients_of_firm.size
|
237
|
-
@signals37.clients_of_firm.delete([@signals37.clients_of_firm[0], @signals37.clients_of_firm[1]])
|
238
|
-
assert_equal 0, @signals37.clients_of_firm.size
|
239
|
-
assert_equal 0, @signals37.clients_of_firm(true).size
|
461
|
+
def test_counting_with_single_conditions
|
462
|
+
assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
|
240
463
|
end
|
241
464
|
|
242
|
-
def
|
243
|
-
|
244
|
-
@signals37.clients_of_firm.create("name" => "Another Client")
|
245
|
-
assert_equal 2, @signals37.clients_of_firm.size
|
246
|
-
@signals37.clients_of_firm.delete(@signals37.clients_of_firm)
|
247
|
-
assert_equal 0, @signals37.clients_of_firm.size
|
248
|
-
assert_equal 0, @signals37.clients_of_firm(true).size
|
465
|
+
def test_counting_with_single_hash
|
466
|
+
assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1')
|
249
467
|
end
|
250
468
|
|
251
|
-
def
|
252
|
-
|
253
|
-
summit = Client.find_first("name = 'Summit'")
|
254
|
-
@signals37.clients_of_firm.delete(summit)
|
255
|
-
assert_equal 1, @signals37.clients_of_firm.size
|
256
|
-
assert_equal 1, @signals37.clients_of_firm(true).size
|
257
|
-
assert_equal 2, summit.client_of
|
469
|
+
def test_counting_with_column_name_and_hash
|
470
|
+
assert_equal 2, Firm.find(:first).plain_clients.count(:all, :conditions => '1=1')
|
258
471
|
end
|
259
472
|
|
260
|
-
def
|
261
|
-
|
262
|
-
assert !@signals37.clients_of_firm.empty?
|
263
|
-
@signals37.clients_of_firm.destroy_all
|
264
|
-
assert @signals37.clients_of_firm.empty?
|
265
|
-
assert @signals37.clients_of_firm(true).empty?
|
473
|
+
def test_finding
|
474
|
+
assert_equal 2, Firm.find(:first).clients.length
|
266
475
|
end
|
267
476
|
|
268
|
-
def
|
269
|
-
assert_equal
|
270
|
-
|
271
|
-
assert_equal
|
477
|
+
def test_find_many_with_merged_options
|
478
|
+
assert_equal 1, companies(:first_firm).limited_clients.size
|
479
|
+
assert_equal 1, companies(:first_firm).limited_clients.find(:all).size
|
480
|
+
assert_equal 2, companies(:first_firm).limited_clients.find(:all, :limit => nil).size
|
272
481
|
end
|
273
482
|
|
274
|
-
def
|
275
|
-
assert_equal
|
276
|
-
|
277
|
-
|
278
|
-
clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end }
|
483
|
+
def test_dynamic_find_should_respect_association_order
|
484
|
+
assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find(:first, :conditions => "type = 'Client'")
|
485
|
+
assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client')
|
486
|
+
end
|
279
487
|
|
280
|
-
|
488
|
+
def test_dynamic_find_order_should_override_association_order
|
489
|
+
assert_equal companies(:first_client), companies(:first_firm).clients_sorted_desc.find(:first, :conditions => "type = 'Client'", :order => 'id')
|
490
|
+
assert_equal companies(:first_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client', :order => 'id')
|
491
|
+
end
|
281
492
|
|
282
|
-
|
493
|
+
def test_dynamic_find_all_should_respect_association_order
|
494
|
+
assert_equal [companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc.find(:all, :conditions => "type = 'Client'")
|
495
|
+
assert_equal [companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc.find_all_by_type('Client')
|
283
496
|
end
|
284
497
|
|
285
|
-
def
|
286
|
-
assert_equal
|
287
|
-
|
288
|
-
assert_equal 1, Account.find_all.length
|
498
|
+
def test_dynamic_find_all_order_should_override_association_order
|
499
|
+
assert_equal [companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc.find(:all, :conditions => "type = 'Client'", :order => 'id')
|
500
|
+
assert_equal [companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc.find_all_by_type('Client', :order => 'id')
|
289
501
|
end
|
290
502
|
|
291
|
-
def
|
292
|
-
|
503
|
+
def test_dynamic_find_all_should_respect_association_limit
|
504
|
+
assert_equal 1, companies(:first_firm).limited_clients.find(:all, :conditions => "type = 'Client'").length
|
505
|
+
assert_equal 1, companies(:first_firm).limited_clients.find_all_by_type('Client').length
|
293
506
|
end
|
294
|
-
end
|
295
507
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
@signals37 = Firm.find(1)
|
508
|
+
def test_dynamic_find_all_limit_should_override_association_limit
|
509
|
+
assert_equal 2, companies(:first_firm).limited_clients.find(:all, :conditions => "type = 'Client'", :limit => 9_000).length
|
510
|
+
assert_equal 2, companies(:first_firm).limited_clients.find_all_by_type('Client', :limit => 9_000).length
|
300
511
|
end
|
301
512
|
|
302
|
-
def
|
303
|
-
|
304
|
-
|
305
|
-
assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
|
513
|
+
def test_triple_equality
|
514
|
+
assert !(Array === Firm.find(:first).clients)
|
515
|
+
assert Firm.find(:first).clients === Array
|
306
516
|
end
|
307
517
|
|
308
|
-
def
|
309
|
-
|
310
|
-
assert_raises(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
|
518
|
+
def test_finding_default_orders
|
519
|
+
assert_equal "Summit", Firm.find(:first).clients.first.name
|
311
520
|
end
|
312
521
|
|
313
|
-
def
|
314
|
-
|
315
|
-
citibank = Account.create("credit_limit" => 10)
|
316
|
-
citibank.firm = apple
|
317
|
-
assert_equal apple.id, citibank.firm_id
|
522
|
+
def test_finding_with_different_class_name_and_order
|
523
|
+
assert_equal "Microsoft", Firm.find(:first).clients_sorted_desc.first.name
|
318
524
|
end
|
319
|
-
|
320
|
-
def
|
321
|
-
|
322
|
-
client.firm = nil
|
323
|
-
client.save
|
324
|
-
assert_nil client.firm(true)
|
325
|
-
assert_nil client.client_of
|
525
|
+
|
526
|
+
def test_finding_with_foreign_key
|
527
|
+
assert_equal "Microsoft", Firm.find(:first).clients_of_firm.first.name
|
326
528
|
end
|
327
|
-
|
328
|
-
def
|
329
|
-
assert_equal
|
330
|
-
assert !Company.find(3).firm_with_other_name.empty?, "Microsoft should have a firm"
|
529
|
+
|
530
|
+
def test_finding_with_condition
|
531
|
+
assert_equal "Microsoft", Firm.find(:first).clients_like_ms.first.name
|
331
532
|
end
|
332
533
|
|
333
|
-
def
|
334
|
-
assert_equal
|
335
|
-
assert !Company.find(3).firm_with_condition.empty?, "Microsoft should have a firm"
|
534
|
+
def test_finding_with_condition_hash
|
535
|
+
assert_equal "Microsoft", Firm.find(:first).clients_like_ms_with_hash_conditions.first.name
|
336
536
|
end
|
337
|
-
|
338
|
-
def test_belongs_to_counter
|
339
|
-
debate = Topic.create("title" => "debate")
|
340
|
-
assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
|
341
537
|
|
342
|
-
|
343
|
-
|
538
|
+
def test_finding_using_sql
|
539
|
+
firm = Firm.find(:first)
|
540
|
+
first_client = firm.clients_using_sql.first
|
541
|
+
assert_not_nil first_client
|
542
|
+
assert_equal "Microsoft", first_client.name
|
543
|
+
assert_equal 1, firm.clients_using_sql.size
|
544
|
+
assert_equal 1, Firm.find(:first).clients_using_sql.size
|
545
|
+
end
|
344
546
|
|
345
|
-
|
346
|
-
assert_equal
|
547
|
+
def test_counting_using_sql
|
548
|
+
assert_equal 1, Firm.find(:first).clients_using_counter_sql.size
|
549
|
+
assert Firm.find(:first).clients_using_counter_sql.any?
|
550
|
+
assert_equal 0, Firm.find(:first).clients_using_zero_counter_sql.size
|
551
|
+
assert !Firm.find(:first).clients_using_zero_counter_sql.any?
|
347
552
|
end
|
348
553
|
|
349
|
-
def
|
350
|
-
|
351
|
-
|
554
|
+
def test_counting_non_existant_items_using_sql
|
555
|
+
assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size
|
556
|
+
end
|
352
557
|
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
apple.companies_count = 2
|
357
|
-
apple.save
|
558
|
+
def test_belongs_to_sanity
|
559
|
+
c = Client.new
|
560
|
+
assert_nil c.firm
|
358
561
|
|
359
|
-
|
360
|
-
|
562
|
+
if c.firm
|
563
|
+
assert false, "belongs_to failed if check"
|
564
|
+
end
|
361
565
|
|
362
|
-
|
363
|
-
|
566
|
+
unless c.firm
|
567
|
+
else
|
568
|
+
assert false, "belongs_to failed unless check"
|
569
|
+
end
|
364
570
|
end
|
365
|
-
end
|
366
571
|
|
572
|
+
def test_find_ids
|
573
|
+
firm = Firm.find(:first)
|
367
574
|
|
368
|
-
|
369
|
-
def setup
|
370
|
-
create_fixtures "accounts"
|
371
|
-
create_fixtures "companies"
|
372
|
-
create_fixtures "accounts"
|
373
|
-
create_fixtures "developers"
|
374
|
-
create_fixtures "projects"
|
375
|
-
create_fixtures "developers_projects"
|
376
|
-
@signals37 = Firm.find(1)
|
377
|
-
end
|
378
|
-
|
379
|
-
def test_has_and_belongs_to_many
|
380
|
-
david = Developer.find(1)
|
575
|
+
assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find }
|
381
576
|
|
382
|
-
|
383
|
-
|
577
|
+
client = firm.clients.find(2)
|
578
|
+
assert_kind_of Client, client
|
384
579
|
|
385
|
-
|
386
|
-
|
387
|
-
assert_equal
|
388
|
-
|
580
|
+
client_ary = firm.clients.find([2])
|
581
|
+
assert_kind_of Array, client_ary
|
582
|
+
assert_equal client, client_ary.first
|
583
|
+
|
584
|
+
client_ary = firm.clients.find(2, 3)
|
585
|
+
assert_kind_of Array, client_ary
|
586
|
+
assert_equal 2, client_ary.size
|
587
|
+
assert_equal client, client_ary.first
|
588
|
+
|
589
|
+
assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find(2, 99) }
|
389
590
|
end
|
390
|
-
|
391
|
-
def
|
591
|
+
|
592
|
+
def test_find_string_ids_when_using_finder_sql
|
593
|
+
firm = Firm.find(:first)
|
594
|
+
|
595
|
+
client = firm.clients_using_finder_sql.find("2")
|
596
|
+
assert_kind_of Client, client
|
597
|
+
|
598
|
+
client_ary = firm.clients_using_finder_sql.find(["2"])
|
599
|
+
assert_kind_of Array, client_ary
|
600
|
+
assert_equal client, client_ary.first
|
601
|
+
|
602
|
+
client_ary = firm.clients_using_finder_sql.find("2", "3")
|
603
|
+
assert_kind_of Array, client_ary
|
604
|
+
assert_equal 2, client_ary.size
|
605
|
+
assert client_ary.include?(client)
|
606
|
+
end
|
607
|
+
|
608
|
+
def test_find_all
|
609
|
+
firm = Firm.find(:first)
|
610
|
+
assert_equal 2, firm.clients.find(:all, :conditions => "#{QUOTED_TYPE} = 'Client'").length
|
611
|
+
assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length
|
612
|
+
end
|
613
|
+
|
614
|
+
def test_find_all_sanitized
|
615
|
+
firm = Firm.find(:first)
|
616
|
+
summit = firm.clients.find(:all, :conditions => "name = 'Summit'")
|
617
|
+
assert_equal summit, firm.clients.find(:all, :conditions => ["name = ?", "Summit"])
|
618
|
+
assert_equal summit, firm.clients.find(:all, :conditions => ["name = :name", { :name => "Summit" }])
|
619
|
+
end
|
620
|
+
|
621
|
+
def test_find_first
|
622
|
+
firm = Firm.find(:first)
|
623
|
+
client2 = Client.find(2)
|
624
|
+
assert_equal firm.clients.first, firm.clients.find(:first)
|
625
|
+
assert_equal client2, firm.clients.find(:first, :conditions => "#{QUOTED_TYPE} = 'Client'")
|
626
|
+
end
|
627
|
+
|
628
|
+
def test_find_first_sanitized
|
629
|
+
firm = Firm.find(:first)
|
630
|
+
client2 = Client.find(2)
|
631
|
+
assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = ?", 'Client'])
|
632
|
+
assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }])
|
633
|
+
end
|
634
|
+
|
635
|
+
def test_find_in_collection
|
636
|
+
assert_equal Client.find(2).name, companies(:first_firm).clients.find(2).name
|
637
|
+
assert_raises(ActiveRecord::RecordNotFound) { companies(:first_firm).clients.find(6) }
|
638
|
+
end
|
639
|
+
|
640
|
+
def test_find_grouped
|
641
|
+
all_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1")
|
642
|
+
grouped_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1", :group => "firm_id", :select => 'firm_id, count(id) as clients_count')
|
643
|
+
assert_equal 2, all_clients_of_firm1.size
|
644
|
+
assert_equal 1, grouped_clients_of_firm1.size
|
645
|
+
end
|
646
|
+
|
647
|
+
def test_adding
|
648
|
+
force_signal37_to_load_all_clients_of_firm
|
649
|
+
natural = Client.new("name" => "Natural Company")
|
650
|
+
companies(:first_firm).clients_of_firm << natural
|
651
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size # checking via the collection
|
652
|
+
assert_equal 2, companies(:first_firm).clients_of_firm(true).size # checking using the db
|
653
|
+
assert_equal natural, companies(:first_firm).clients_of_firm.last
|
654
|
+
end
|
655
|
+
|
656
|
+
def test_adding_using_create
|
657
|
+
first_firm = companies(:first_firm)
|
658
|
+
assert_equal 2, first_firm.plain_clients.size
|
659
|
+
natural = first_firm.plain_clients.create(:name => "Natural Company")
|
660
|
+
assert_equal 3, first_firm.plain_clients.length
|
661
|
+
assert_equal 3, first_firm.plain_clients.size
|
662
|
+
end
|
663
|
+
|
664
|
+
def test_create_with_bang_on_has_many_when_parent_is_new_raises
|
665
|
+
assert_raises(ActiveRecord::RecordNotSaved) do
|
666
|
+
firm = Firm.new
|
667
|
+
firm.plain_clients.create! :name=>"Whoever"
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
671
|
+
def test_regular_create_on_has_many_when_parent_is_new_raises
|
672
|
+
assert_raises(ActiveRecord::RecordNotSaved) do
|
673
|
+
firm = Firm.new
|
674
|
+
firm.plain_clients.create :name=>"Whoever"
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
def test_create_with_bang_on_has_many_raises_when_record_not_saved
|
679
|
+
assert_raises(ActiveRecord::RecordInvalid) do
|
680
|
+
firm = Firm.find(:first)
|
681
|
+
firm.plain_clients.create!
|
682
|
+
end
|
683
|
+
end
|
684
|
+
|
685
|
+
def test_create_with_bang_on_habtm_when_parent_is_new_raises
|
686
|
+
assert_raises(ActiveRecord::RecordNotSaved) do
|
687
|
+
Developer.new("name" => "Aredridel").projects.create!
|
688
|
+
end
|
689
|
+
end
|
690
|
+
|
691
|
+
def test_adding_a_mismatch_class
|
692
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil }
|
693
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 }
|
694
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << Topic.find(1) }
|
695
|
+
end
|
696
|
+
|
697
|
+
def test_adding_a_collection
|
698
|
+
force_signal37_to_load_all_clients_of_firm
|
699
|
+
companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")])
|
700
|
+
assert_equal 3, companies(:first_firm).clients_of_firm.size
|
701
|
+
assert_equal 3, companies(:first_firm).clients_of_firm(true).size
|
702
|
+
end
|
703
|
+
|
704
|
+
def test_adding_before_save
|
705
|
+
no_of_firms = Firm.count
|
706
|
+
no_of_clients = Client.count
|
707
|
+
|
708
|
+
new_firm = Firm.new("name" => "A New Firm, Inc")
|
709
|
+
c = Client.new("name" => "Apple")
|
710
|
+
|
711
|
+
new_firm.clients_of_firm.push Client.new("name" => "Natural Company")
|
712
|
+
assert_equal 1, new_firm.clients_of_firm.size
|
713
|
+
new_firm.clients_of_firm << c
|
714
|
+
assert_equal 2, new_firm.clients_of_firm.size
|
715
|
+
|
716
|
+
assert_equal no_of_firms, Firm.count # Firm was not saved to database.
|
717
|
+
assert_equal no_of_clients, Client.count # Clients were not saved to database.
|
718
|
+
assert new_firm.save
|
719
|
+
assert !new_firm.new_record?
|
720
|
+
assert !c.new_record?
|
721
|
+
assert_equal new_firm, c.firm
|
722
|
+
assert_equal no_of_firms+1, Firm.count # Firm was saved to database.
|
723
|
+
assert_equal no_of_clients+2, Client.count # Clients were saved to database.
|
724
|
+
|
725
|
+
assert_equal 2, new_firm.clients_of_firm.size
|
726
|
+
assert_equal 2, new_firm.clients_of_firm(true).size
|
727
|
+
end
|
728
|
+
|
729
|
+
def test_invalid_adding
|
730
|
+
firm = Firm.find(1)
|
731
|
+
assert !(firm.clients_of_firm << c = Client.new)
|
732
|
+
assert c.new_record?
|
733
|
+
assert !firm.valid?
|
734
|
+
assert !firm.save
|
735
|
+
assert c.new_record?
|
736
|
+
end
|
737
|
+
|
738
|
+
def test_invalid_adding_before_save
|
739
|
+
no_of_firms = Firm.count
|
740
|
+
no_of_clients = Client.count
|
741
|
+
new_firm = Firm.new("name" => "A New Firm, Inc")
|
742
|
+
new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")])
|
743
|
+
assert c.new_record?
|
744
|
+
assert !c.valid?
|
745
|
+
assert !new_firm.valid?
|
746
|
+
assert !new_firm.save
|
747
|
+
assert c.new_record?
|
748
|
+
assert new_firm.new_record?
|
749
|
+
end
|
750
|
+
|
751
|
+
def test_build
|
752
|
+
new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client")
|
753
|
+
assert_equal "Another Client", new_client.name
|
754
|
+
assert new_client.new_record?
|
755
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm.last
|
756
|
+
assert companies(:first_firm).save
|
757
|
+
assert !new_client.new_record?
|
758
|
+
assert_equal 2, companies(:first_firm).clients_of_firm(true).size
|
759
|
+
end
|
760
|
+
|
761
|
+
def test_build_many
|
762
|
+
new_clients = companies(:first_firm).clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}])
|
763
|
+
assert_equal 2, new_clients.size
|
764
|
+
|
765
|
+
assert companies(:first_firm).save
|
766
|
+
assert_equal 3, companies(:first_firm).clients_of_firm(true).size
|
767
|
+
end
|
768
|
+
|
769
|
+
def test_build_without_loading_association
|
770
|
+
first_topic = topics(:first)
|
771
|
+
Reply.column_names
|
772
|
+
|
773
|
+
assert_equal 1, first_topic.replies.length
|
774
|
+
|
775
|
+
assert_no_queries do
|
776
|
+
first_topic.replies.build(:title => "Not saved", :content => "Superstars")
|
777
|
+
assert_equal 2, first_topic.replies.size
|
778
|
+
end
|
779
|
+
|
780
|
+
assert_equal 2, first_topic.replies.to_ary.size
|
781
|
+
end
|
782
|
+
|
783
|
+
def test_create_without_loading_association
|
784
|
+
first_firm = companies(:first_firm)
|
785
|
+
Firm.column_names
|
786
|
+
Client.column_names
|
787
|
+
|
788
|
+
assert_equal 1, first_firm.clients_of_firm.size
|
789
|
+
first_firm.clients_of_firm.reset
|
790
|
+
|
791
|
+
assert_queries(1) do
|
792
|
+
first_firm.clients_of_firm.create(:name => "Superstars")
|
793
|
+
end
|
794
|
+
|
795
|
+
assert_equal 2, first_firm.clients_of_firm.size
|
796
|
+
end
|
797
|
+
|
798
|
+
def test_invalid_build
|
799
|
+
new_client = companies(:first_firm).clients_of_firm.build
|
800
|
+
assert new_client.new_record?
|
801
|
+
assert !new_client.valid?
|
802
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm.last
|
803
|
+
assert !companies(:first_firm).save
|
804
|
+
assert new_client.new_record?
|
805
|
+
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
|
806
|
+
end
|
807
|
+
|
808
|
+
def test_create
|
809
|
+
force_signal37_to_load_all_clients_of_firm
|
810
|
+
new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
811
|
+
assert !new_client.new_record?
|
812
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm.last
|
813
|
+
assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
|
814
|
+
end
|
815
|
+
|
816
|
+
def test_create_many
|
817
|
+
companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
|
818
|
+
assert_equal 3, companies(:first_firm).clients_of_firm(true).size
|
819
|
+
end
|
820
|
+
|
821
|
+
def test_find_or_initialize
|
822
|
+
the_client = companies(:first_firm).clients.find_or_initialize_by_name("Yet another client")
|
823
|
+
assert_equal companies(:first_firm).id, the_client.firm_id
|
824
|
+
assert_equal "Yet another client", the_client.name
|
825
|
+
assert the_client.new_record?
|
826
|
+
end
|
827
|
+
|
828
|
+
def test_find_or_create
|
829
|
+
number_of_clients = companies(:first_firm).clients.size
|
830
|
+
the_client = companies(:first_firm).clients.find_or_create_by_name("Yet another client")
|
831
|
+
assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
|
832
|
+
assert_equal the_client, companies(:first_firm).clients.find_or_create_by_name("Yet another client")
|
833
|
+
assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
|
834
|
+
end
|
835
|
+
|
836
|
+
def test_deleting
|
837
|
+
force_signal37_to_load_all_clients_of_firm
|
838
|
+
companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first)
|
839
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
840
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
841
|
+
end
|
842
|
+
|
843
|
+
def test_deleting_before_save
|
844
|
+
new_firm = Firm.new("name" => "A New Firm, Inc.")
|
845
|
+
new_client = new_firm.clients_of_firm.build("name" => "Another Client")
|
846
|
+
assert_equal 1, new_firm.clients_of_firm.size
|
847
|
+
new_firm.clients_of_firm.delete(new_client)
|
848
|
+
assert_equal 0, new_firm.clients_of_firm.size
|
849
|
+
end
|
850
|
+
|
851
|
+
def test_deleting_a_collection
|
852
|
+
force_signal37_to_load_all_clients_of_firm
|
853
|
+
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
854
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size
|
855
|
+
companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]])
|
856
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
857
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
858
|
+
end
|
859
|
+
|
860
|
+
def test_delete_all
|
861
|
+
force_signal37_to_load_all_clients_of_firm
|
862
|
+
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
863
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size
|
864
|
+
companies(:first_firm).clients_of_firm.delete_all
|
865
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
866
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
867
|
+
end
|
868
|
+
|
869
|
+
def test_delete_all_with_not_yet_loaded_association_collection
|
870
|
+
force_signal37_to_load_all_clients_of_firm
|
871
|
+
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
|
872
|
+
assert_equal 2, companies(:first_firm).clients_of_firm.size
|
873
|
+
companies(:first_firm).clients_of_firm.reset
|
874
|
+
companies(:first_firm).clients_of_firm.delete_all
|
875
|
+
assert_equal 0, companies(:first_firm).clients_of_firm.size
|
876
|
+
assert_equal 0, companies(:first_firm).clients_of_firm(true).size
|
877
|
+
end
|
878
|
+
|
879
|
+
def test_clearing_an_association_collection
|
880
|
+
firm = companies(:first_firm)
|
881
|
+
client_id = firm.clients_of_firm.first.id
|
882
|
+
assert_equal 1, firm.clients_of_firm.size
|
883
|
+
|
884
|
+
firm.clients_of_firm.clear
|
885
|
+
|
886
|
+
assert_equal 0, firm.clients_of_firm.size
|
887
|
+
assert_equal 0, firm.clients_of_firm(true).size
|
888
|
+
assert_equal [], Client.destroyed_client_ids[firm.id]
|
889
|
+
|
890
|
+
# Should not be destroyed since the association is not dependent.
|
891
|
+
assert_nothing_raised do
|
892
|
+
assert Client.find(client_id).firm.nil?
|
893
|
+
end
|
894
|
+
end
|
895
|
+
|
896
|
+
def test_clearing_a_dependent_association_collection
|
897
|
+
firm = companies(:first_firm)
|
898
|
+
client_id = firm.dependent_clients_of_firm.first.id
|
899
|
+
assert_equal 1, firm.dependent_clients_of_firm.size
|
900
|
+
|
901
|
+
# :dependent means destroy is called on each client
|
902
|
+
firm.dependent_clients_of_firm.clear
|
903
|
+
|
904
|
+
assert_equal 0, firm.dependent_clients_of_firm.size
|
905
|
+
assert_equal 0, firm.dependent_clients_of_firm(true).size
|
906
|
+
assert_equal [client_id], Client.destroyed_client_ids[firm.id]
|
907
|
+
|
908
|
+
# Should be destroyed since the association is dependent.
|
909
|
+
assert Client.find_by_id(client_id).nil?
|
910
|
+
end
|
911
|
+
|
912
|
+
def test_clearing_an_exclusively_dependent_association_collection
|
913
|
+
firm = companies(:first_firm)
|
914
|
+
client_id = firm.exclusively_dependent_clients_of_firm.first.id
|
915
|
+
assert_equal 1, firm.exclusively_dependent_clients_of_firm.size
|
916
|
+
|
917
|
+
assert_equal [], Client.destroyed_client_ids[firm.id]
|
918
|
+
|
919
|
+
# :exclusively_dependent means each client is deleted directly from
|
920
|
+
# the database without looping through them calling destroy.
|
921
|
+
firm.exclusively_dependent_clients_of_firm.clear
|
922
|
+
|
923
|
+
assert_equal 0, firm.exclusively_dependent_clients_of_firm.size
|
924
|
+
assert_equal 0, firm.exclusively_dependent_clients_of_firm(true).size
|
925
|
+
# no destroy-filters should have been called
|
926
|
+
assert_equal [], Client.destroyed_client_ids[firm.id]
|
927
|
+
|
928
|
+
# Should be destroyed since the association is exclusively dependent.
|
929
|
+
assert Client.find_by_id(client_id).nil?
|
930
|
+
end
|
931
|
+
|
932
|
+
def test_dependent_association_respects_optional_conditions_on_delete
|
933
|
+
firm = companies(:odegy)
|
934
|
+
Client.create(:client_of => firm.id, :name => "BigShot Inc.")
|
935
|
+
Client.create(:client_of => firm.id, :name => "SmallTime Inc.")
|
936
|
+
# only one of two clients is included in the association due to the :conditions key
|
937
|
+
assert_equal 2, Client.find_all_by_client_of(firm.id).size
|
938
|
+
assert_equal 1, firm.dependent_conditional_clients_of_firm.size
|
939
|
+
firm.destroy
|
940
|
+
# only the correctly associated client should have been deleted
|
941
|
+
assert_equal 1, Client.find_all_by_client_of(firm.id).size
|
942
|
+
end
|
943
|
+
|
944
|
+
def test_dependent_association_respects_optional_sanitized_conditions_on_delete
|
945
|
+
firm = companies(:odegy)
|
946
|
+
Client.create(:client_of => firm.id, :name => "BigShot Inc.")
|
947
|
+
Client.create(:client_of => firm.id, :name => "SmallTime Inc.")
|
948
|
+
# only one of two clients is included in the association due to the :conditions key
|
949
|
+
assert_equal 2, Client.find_all_by_client_of(firm.id).size
|
950
|
+
assert_equal 1, firm.dependent_sanitized_conditional_clients_of_firm.size
|
951
|
+
firm.destroy
|
952
|
+
# only the correctly associated client should have been deleted
|
953
|
+
assert_equal 1, Client.find_all_by_client_of(firm.id).size
|
954
|
+
end
|
955
|
+
|
956
|
+
def test_clearing_without_initial_access
|
957
|
+
firm = companies(:first_firm)
|
958
|
+
|
959
|
+
firm.clients_of_firm.clear
|
960
|
+
|
961
|
+
assert_equal 0, firm.clients_of_firm.size
|
962
|
+
assert_equal 0, firm.clients_of_firm(true).size
|
963
|
+
end
|
964
|
+
|
965
|
+
def test_deleting_a_item_which_is_not_in_the_collection
|
966
|
+
force_signal37_to_load_all_clients_of_firm
|
967
|
+
summit = Client.find_by_name('Summit')
|
968
|
+
companies(:first_firm).clients_of_firm.delete(summit)
|
969
|
+
assert_equal 1, companies(:first_firm).clients_of_firm.size
|
970
|
+
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
|
971
|
+
assert_equal 2, summit.client_of
|
972
|
+
end
|
973
|
+
|
974
|
+
def test_deleting_type_mismatch
|
975
|
+
david = Developer.find(1)
|
976
|
+
david.projects.reload
|
977
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(1) }
|
978
|
+
end
|
979
|
+
|
980
|
+
def test_deleting_self_type_mismatch
|
981
|
+
david = Developer.find(1)
|
982
|
+
david.projects.reload
|
983
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(Project.find(1).developers) }
|
984
|
+
end
|
985
|
+
|
986
|
+
def test_destroy_all
|
987
|
+
force_signal37_to_load_all_clients_of_firm
|
988
|
+
assert !companies(:first_firm).clients_of_firm.empty?, "37signals has clients after load"
|
989
|
+
companies(:first_firm).clients_of_firm.destroy_all
|
990
|
+
assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all"
|
991
|
+
assert companies(:first_firm).clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh"
|
992
|
+
end
|
993
|
+
|
994
|
+
def test_dependence
|
995
|
+
firm = companies(:first_firm)
|
996
|
+
assert_equal 2, firm.clients.size
|
997
|
+
firm.destroy
|
998
|
+
assert Client.find(:all, :conditions => "firm_id=#{firm.id}").empty?
|
999
|
+
end
|
1000
|
+
|
1001
|
+
def test_destroy_dependent_when_deleted_from_association
|
1002
|
+
firm = Firm.find(:first)
|
1003
|
+
assert_equal 2, firm.clients.size
|
1004
|
+
|
1005
|
+
client = firm.clients.first
|
1006
|
+
firm.clients.delete(client)
|
1007
|
+
|
1008
|
+
assert_raise(ActiveRecord::RecordNotFound) { Client.find(client.id) }
|
1009
|
+
assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(client.id) }
|
1010
|
+
assert_equal 1, firm.clients.size
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
def test_three_levels_of_dependence
|
1014
|
+
topic = Topic.create "title" => "neat and simple"
|
1015
|
+
reply = topic.replies.create "title" => "neat and simple", "content" => "still digging it"
|
1016
|
+
silly_reply = reply.replies.create "title" => "neat and simple", "content" => "ain't complaining"
|
1017
|
+
|
1018
|
+
assert_nothing_raised { topic.destroy }
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
uses_transaction :test_dependence_with_transaction_support_on_failure
|
1022
|
+
def test_dependence_with_transaction_support_on_failure
|
1023
|
+
firm = companies(:first_firm)
|
1024
|
+
clients = firm.clients
|
1025
|
+
assert_equal 2, clients.length
|
1026
|
+
clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end }
|
1027
|
+
|
1028
|
+
firm.destroy rescue "do nothing"
|
1029
|
+
|
1030
|
+
assert_equal 2, Client.find(:all, :conditions => "firm_id=#{firm.id}").size
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
def test_dependence_on_account
|
1034
|
+
num_accounts = Account.count
|
1035
|
+
companies(:first_firm).destroy
|
1036
|
+
assert_equal num_accounts - 1, Account.count
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
def test_depends_and_nullify
|
1040
|
+
num_accounts = Account.count
|
1041
|
+
num_companies = Company.count
|
1042
|
+
|
1043
|
+
core = companies(:rails_core)
|
1044
|
+
assert_equal accounts(:rails_core_account), core.account
|
1045
|
+
assert_equal companies(:leetsoft, :jadedpixel), core.companies
|
1046
|
+
core.destroy
|
1047
|
+
assert_nil accounts(:rails_core_account).reload.firm_id
|
1048
|
+
assert_nil companies(:leetsoft).reload.client_of
|
1049
|
+
assert_nil companies(:jadedpixel).reload.client_of
|
1050
|
+
|
1051
|
+
|
1052
|
+
assert_equal num_accounts, Account.count
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
def test_included_in_collection
|
1056
|
+
assert companies(:first_firm).clients.include?(Client.find(2))
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
def test_adding_array_and_collection
|
1060
|
+
assert_nothing_raised { Firm.find(:first).clients + Firm.find(:all).last.clients }
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
def test_find_all_without_conditions
|
1064
|
+
firm = companies(:first_firm)
|
1065
|
+
assert_equal 2, firm.clients.find(:all).length
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
def test_replace_with_less
|
1069
|
+
firm = Firm.find(:first)
|
1070
|
+
firm.clients = [companies(:first_client)]
|
1071
|
+
assert firm.save, "Could not save firm"
|
1072
|
+
firm.reload
|
1073
|
+
assert_equal 1, firm.clients.length
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
def test_replace_with_less_and_dependent_nullify
|
1077
|
+
num_companies = Company.count
|
1078
|
+
companies(:rails_core).companies = []
|
1079
|
+
assert_equal num_companies, Company.count
|
1080
|
+
end
|
1081
|
+
|
1082
|
+
def test_replace_with_new
|
1083
|
+
firm = Firm.find(:first)
|
1084
|
+
firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
|
1085
|
+
firm.save
|
1086
|
+
firm.reload
|
1087
|
+
assert_equal 2, firm.clients.length
|
1088
|
+
assert !firm.clients.include?(:first_client)
|
1089
|
+
end
|
1090
|
+
|
1091
|
+
def test_replace_on_new_object
|
1092
|
+
firm = Firm.new("name" => "New Firm")
|
1093
|
+
firm.clients = [companies(:second_client), Client.new("name" => "New Client")]
|
1094
|
+
assert firm.save
|
1095
|
+
firm.reload
|
1096
|
+
assert_equal 2, firm.clients.length
|
1097
|
+
assert firm.clients.include?(Client.find_by_name("New Client"))
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
def test_get_ids
|
1101
|
+
assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
def test_assign_ids
|
1105
|
+
firm = Firm.new("name" => "Apple")
|
1106
|
+
firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
|
1107
|
+
firm.save
|
1108
|
+
firm.reload
|
1109
|
+
assert_equal 2, firm.clients.length
|
1110
|
+
assert firm.clients.include?(companies(:second_client))
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
def test_assign_ids_ignoring_blanks
|
1114
|
+
firm = Firm.create!(:name => 'Apple')
|
1115
|
+
firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id, '']
|
1116
|
+
firm.save!
|
1117
|
+
|
1118
|
+
assert_equal 2, firm.clients(true).size
|
1119
|
+
assert firm.clients.include?(companies(:second_client))
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
def test_get_ids_for_through
|
1123
|
+
assert_equal [comments(:eager_other_comment1).id], authors(:mary).comment_ids
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
def test_assign_ids_for_through
|
1127
|
+
assert_raise(NoMethodError) { authors(:mary).comment_ids = [123] }
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
def test_dynamic_find_should_respect_association_order_for_through
|
1131
|
+
assert_equal Comment.find(10), authors(:david).comments_desc.find(:first, :conditions => "comments.type = 'SpecialComment'")
|
1132
|
+
assert_equal Comment.find(10), authors(:david).comments_desc.find_by_type('SpecialComment')
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
def test_dynamic_find_order_should_override_association_order_for_through
|
1136
|
+
assert_equal Comment.find(3), authors(:david).comments_desc.find(:first, :conditions => "comments.type = 'SpecialComment'", :order => 'comments.id')
|
1137
|
+
assert_equal Comment.find(3), authors(:david).comments_desc.find_by_type('SpecialComment', :order => 'comments.id')
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
def test_dynamic_find_all_should_respect_association_order_for_through
|
1141
|
+
assert_equal [Comment.find(10), Comment.find(7), Comment.find(6), Comment.find(3)], authors(:david).comments_desc.find(:all, :conditions => "comments.type = 'SpecialComment'")
|
1142
|
+
assert_equal [Comment.find(10), Comment.find(7), Comment.find(6), Comment.find(3)], authors(:david).comments_desc.find_all_by_type('SpecialComment')
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
def test_dynamic_find_all_order_should_override_association_order_for_through
|
1146
|
+
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')
|
1147
|
+
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')
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
def test_dynamic_find_all_should_respect_association_limit_for_through
|
1151
|
+
assert_equal 1, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'").length
|
1152
|
+
assert_equal 1, authors(:david).limited_comments.find_all_by_type('SpecialComment').length
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
def test_dynamic_find_all_order_should_override_association_limit_for_through
|
1156
|
+
assert_equal 4, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'", :limit => 9_000).length
|
1157
|
+
assert_equal 4, authors(:david).limited_comments.find_all_by_type('SpecialComment', :limit => 9_000).length
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
class BelongsToAssociationsTest < Test::Unit::TestCase
|
1163
|
+
fixtures :accounts, :companies, :developers, :projects, :topics,
|
1164
|
+
:developers_projects, :computers, :authors, :posts, :tags, :taggings
|
1165
|
+
|
1166
|
+
def test_belongs_to
|
1167
|
+
Client.find(3).firm.name
|
1168
|
+
assert_equal companies(:first_firm).name, Client.find(3).firm.name
|
1169
|
+
assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
|
1170
|
+
end
|
1171
|
+
|
1172
|
+
def test_proxy_assignment
|
1173
|
+
account = Account.find(1)
|
1174
|
+
assert_nothing_raised { account.firm = account.firm }
|
1175
|
+
end
|
1176
|
+
|
1177
|
+
def test_triple_equality
|
1178
|
+
assert Client.find(3).firm === Firm
|
1179
|
+
assert Firm === Client.find(3).firm
|
1180
|
+
end
|
1181
|
+
|
1182
|
+
def test_type_mismatch
|
1183
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
|
1184
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
def test_natural_assignment
|
1188
|
+
apple = Firm.create("name" => "Apple")
|
1189
|
+
citibank = Account.create("credit_limit" => 10)
|
1190
|
+
citibank.firm = apple
|
1191
|
+
assert_equal apple.id, citibank.firm_id
|
1192
|
+
end
|
1193
|
+
|
1194
|
+
def test_no_unexpected_aliasing
|
1195
|
+
first_firm = companies(:first_firm)
|
1196
|
+
another_firm = companies(:another_firm)
|
1197
|
+
|
1198
|
+
citibank = Account.create("credit_limit" => 10)
|
1199
|
+
citibank.firm = first_firm
|
1200
|
+
original_proxy = citibank.firm
|
1201
|
+
citibank.firm = another_firm
|
1202
|
+
|
1203
|
+
assert_equal first_firm.object_id, original_proxy.object_id
|
1204
|
+
assert_equal another_firm.object_id, citibank.firm.object_id
|
1205
|
+
end
|
1206
|
+
|
1207
|
+
def test_creating_the_belonging_object
|
1208
|
+
citibank = Account.create("credit_limit" => 10)
|
1209
|
+
apple = citibank.create_firm("name" => "Apple")
|
1210
|
+
assert_equal apple, citibank.firm
|
1211
|
+
citibank.save
|
1212
|
+
citibank.reload
|
1213
|
+
assert_equal apple, citibank.firm
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
def test_building_the_belonging_object
|
1217
|
+
citibank = Account.create("credit_limit" => 10)
|
1218
|
+
apple = citibank.build_firm("name" => "Apple")
|
1219
|
+
citibank.save
|
1220
|
+
assert_equal apple.id, citibank.firm_id
|
1221
|
+
end
|
1222
|
+
|
1223
|
+
def test_natural_assignment_to_nil
|
1224
|
+
client = Client.find(3)
|
1225
|
+
client.firm = nil
|
1226
|
+
client.save
|
1227
|
+
assert_nil client.firm(true)
|
1228
|
+
assert_nil client.client_of
|
1229
|
+
end
|
1230
|
+
|
1231
|
+
def test_with_different_class_name
|
1232
|
+
assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
|
1233
|
+
assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
|
1234
|
+
end
|
1235
|
+
|
1236
|
+
def test_with_condition
|
1237
|
+
assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
|
1238
|
+
assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
|
1239
|
+
end
|
1240
|
+
|
1241
|
+
def test_belongs_to_counter
|
1242
|
+
debate = Topic.create("title" => "debate")
|
1243
|
+
assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
|
1244
|
+
|
1245
|
+
trash = debate.replies.create("title" => "blah!", "content" => "world around!")
|
1246
|
+
assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created"
|
1247
|
+
|
1248
|
+
trash.destroy
|
1249
|
+
assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
|
1250
|
+
end
|
1251
|
+
|
1252
|
+
def test_belongs_to_counter_with_reassigning
|
1253
|
+
t1 = Topic.create("title" => "t1")
|
1254
|
+
t2 = Topic.create("title" => "t2")
|
1255
|
+
r1 = Reply.new("title" => "r1", "content" => "r1")
|
1256
|
+
r1.topic = t1
|
1257
|
+
|
1258
|
+
assert r1.save
|
1259
|
+
assert_equal 1, Topic.find(t1.id).replies.size
|
1260
|
+
assert_equal 0, Topic.find(t2.id).replies.size
|
1261
|
+
|
1262
|
+
r1.topic = Topic.find(t2.id)
|
1263
|
+
|
1264
|
+
assert r1.save
|
1265
|
+
assert_equal 0, Topic.find(t1.id).replies.size
|
1266
|
+
assert_equal 1, Topic.find(t2.id).replies.size
|
1267
|
+
|
1268
|
+
r1.topic = nil
|
1269
|
+
|
1270
|
+
assert_equal 0, Topic.find(t1.id).replies.size
|
1271
|
+
assert_equal 0, Topic.find(t2.id).replies.size
|
1272
|
+
|
1273
|
+
r1.topic = t1
|
1274
|
+
|
1275
|
+
assert_equal 1, Topic.find(t1.id).replies.size
|
1276
|
+
assert_equal 0, Topic.find(t2.id).replies.size
|
1277
|
+
|
1278
|
+
r1.destroy
|
1279
|
+
|
1280
|
+
assert_equal 0, Topic.find(t1.id).replies.size
|
1281
|
+
assert_equal 0, Topic.find(t2.id).replies.size
|
1282
|
+
end
|
1283
|
+
|
1284
|
+
def test_belongs_to_counter_after_save
|
1285
|
+
topic = Topic.create!(:title => "monday night")
|
1286
|
+
topic.replies.create!(:title => "re: monday night", :content => "football")
|
1287
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
1288
|
+
|
1289
|
+
topic.save!
|
1290
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
def test_belongs_to_counter_after_update_attributes
|
1294
|
+
topic = Topic.create!(:title => "37s")
|
1295
|
+
topic.replies.create!(:title => "re: 37s", :content => "rails")
|
1296
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
1297
|
+
|
1298
|
+
topic.update_attributes(:title => "37signals")
|
1299
|
+
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
1300
|
+
end
|
1301
|
+
|
1302
|
+
def test_belongs_to_counter_after_save
|
1303
|
+
topic = Topic.create("title" => "monday night")
|
1304
|
+
topic.replies.create("title" => "re: monday night", "content" => "football")
|
1305
|
+
assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
|
1306
|
+
|
1307
|
+
topic.save
|
1308
|
+
assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
def test_belongs_to_counter_after_update_attributes
|
1312
|
+
topic = Topic.create("title" => "37s")
|
1313
|
+
topic.replies.create("title" => "re: 37s", "content" => "rails")
|
1314
|
+
assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
|
1315
|
+
|
1316
|
+
topic.update_attributes("title" => "37signals")
|
1317
|
+
assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
|
1318
|
+
end
|
1319
|
+
|
1320
|
+
def test_assignment_before_parent_saved
|
1321
|
+
client = Client.find(:first)
|
1322
|
+
apple = Firm.new("name" => "Apple")
|
1323
|
+
client.firm = apple
|
1324
|
+
assert_equal apple, client.firm
|
1325
|
+
assert apple.new_record?
|
1326
|
+
assert client.save
|
1327
|
+
assert apple.save
|
1328
|
+
assert !apple.new_record?
|
1329
|
+
assert_equal apple, client.firm
|
1330
|
+
assert_equal apple, client.firm(true)
|
1331
|
+
end
|
1332
|
+
|
1333
|
+
def test_assignment_before_child_saved
|
1334
|
+
final_cut = Client.new("name" => "Final Cut")
|
1335
|
+
firm = Firm.find(1)
|
1336
|
+
final_cut.firm = firm
|
1337
|
+
assert final_cut.new_record?
|
1338
|
+
assert final_cut.save
|
1339
|
+
assert !final_cut.new_record?
|
1340
|
+
assert !firm.new_record?
|
1341
|
+
assert_equal firm, final_cut.firm
|
1342
|
+
assert_equal firm, final_cut.firm(true)
|
1343
|
+
end
|
1344
|
+
|
1345
|
+
def test_assignment_before_either_saved
|
1346
|
+
final_cut = Client.new("name" => "Final Cut")
|
1347
|
+
apple = Firm.new("name" => "Apple")
|
1348
|
+
final_cut.firm = apple
|
1349
|
+
assert final_cut.new_record?
|
1350
|
+
assert apple.new_record?
|
1351
|
+
assert final_cut.save
|
1352
|
+
assert !final_cut.new_record?
|
1353
|
+
assert !apple.new_record?
|
1354
|
+
assert_equal apple, final_cut.firm
|
1355
|
+
assert_equal apple, final_cut.firm(true)
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
def test_new_record_with_foreign_key_but_no_object
|
1359
|
+
c = Client.new("firm_id" => 1)
|
1360
|
+
assert_equal Firm.find(:first), c.firm_with_basic_id
|
1361
|
+
end
|
1362
|
+
|
1363
|
+
def test_forgetting_the_load_when_foreign_key_enters_late
|
1364
|
+
c = Client.new
|
1365
|
+
assert_nil c.firm_with_basic_id
|
1366
|
+
|
1367
|
+
c.firm_id = 1
|
1368
|
+
assert_equal Firm.find(:first), c.firm_with_basic_id
|
1369
|
+
end
|
1370
|
+
|
1371
|
+
def test_field_name_same_as_foreign_key
|
1372
|
+
computer = Computer.find(1)
|
1373
|
+
assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
def test_counter_cache
|
1377
|
+
topic = Topic.create :title => "Zoom-zoom-zoom"
|
1378
|
+
assert_equal 0, topic[:replies_count]
|
1379
|
+
|
1380
|
+
reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
|
1381
|
+
reply.topic = topic
|
1382
|
+
|
1383
|
+
assert_equal 1, topic.reload[:replies_count]
|
1384
|
+
assert_equal 1, topic.replies.size
|
1385
|
+
|
1386
|
+
topic[:replies_count] = 15
|
1387
|
+
assert_equal 15, topic.replies.size
|
1388
|
+
end
|
1389
|
+
|
1390
|
+
def test_custom_counter_cache
|
1391
|
+
reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
|
1392
|
+
assert_equal 0, reply[:replies_count]
|
1393
|
+
|
1394
|
+
silly = SillyReply.create(:title => "gaga", :content => "boo-boo")
|
1395
|
+
silly.reply = reply
|
1396
|
+
|
1397
|
+
assert_equal 1, reply.reload[:replies_count]
|
1398
|
+
assert_equal 1, reply.replies.size
|
1399
|
+
|
1400
|
+
reply[:replies_count] = 17
|
1401
|
+
assert_equal 17, reply.replies.size
|
1402
|
+
end
|
1403
|
+
|
1404
|
+
def test_store_two_association_with_one_save
|
1405
|
+
num_orders = Order.count
|
1406
|
+
num_customers = Customer.count
|
1407
|
+
order = Order.new
|
1408
|
+
|
1409
|
+
customer1 = order.billing = Customer.new
|
1410
|
+
customer2 = order.shipping = Customer.new
|
1411
|
+
assert order.save
|
1412
|
+
assert_equal customer1, order.billing
|
1413
|
+
assert_equal customer2, order.shipping
|
1414
|
+
|
1415
|
+
order.reload
|
1416
|
+
|
1417
|
+
assert_equal customer1, order.billing
|
1418
|
+
assert_equal customer2, order.shipping
|
1419
|
+
|
1420
|
+
assert_equal num_orders +1, Order.count
|
1421
|
+
assert_equal num_customers +2, Customer.count
|
1422
|
+
end
|
1423
|
+
|
1424
|
+
|
1425
|
+
def test_store_association_in_two_relations_with_one_save
|
1426
|
+
num_orders = Order.count
|
1427
|
+
num_customers = Customer.count
|
1428
|
+
order = Order.new
|
1429
|
+
|
1430
|
+
customer = order.billing = order.shipping = Customer.new
|
1431
|
+
assert order.save
|
1432
|
+
assert_equal customer, order.billing
|
1433
|
+
assert_equal customer, order.shipping
|
1434
|
+
|
1435
|
+
order.reload
|
1436
|
+
|
1437
|
+
assert_equal customer, order.billing
|
1438
|
+
assert_equal customer, order.shipping
|
1439
|
+
|
1440
|
+
assert_equal num_orders +1, Order.count
|
1441
|
+
assert_equal num_customers +1, Customer.count
|
1442
|
+
end
|
1443
|
+
|
1444
|
+
def test_store_association_in_two_relations_with_one_save_in_existing_object
|
1445
|
+
num_orders = Order.count
|
1446
|
+
num_customers = Customer.count
|
1447
|
+
order = Order.create
|
1448
|
+
|
1449
|
+
customer = order.billing = order.shipping = Customer.new
|
1450
|
+
assert order.save
|
1451
|
+
assert_equal customer, order.billing
|
1452
|
+
assert_equal customer, order.shipping
|
1453
|
+
|
1454
|
+
order.reload
|
1455
|
+
|
1456
|
+
assert_equal customer, order.billing
|
1457
|
+
assert_equal customer, order.shipping
|
1458
|
+
|
1459
|
+
assert_equal num_orders +1, Order.count
|
1460
|
+
assert_equal num_customers +1, Customer.count
|
1461
|
+
end
|
1462
|
+
|
1463
|
+
def test_store_association_in_two_relations_with_one_save_in_existing_object_with_values
|
1464
|
+
num_orders = Order.count
|
1465
|
+
num_customers = Customer.count
|
1466
|
+
order = Order.create
|
1467
|
+
|
1468
|
+
customer = order.billing = order.shipping = Customer.new
|
1469
|
+
assert order.save
|
1470
|
+
assert_equal customer, order.billing
|
1471
|
+
assert_equal customer, order.shipping
|
1472
|
+
|
1473
|
+
order.reload
|
1474
|
+
|
1475
|
+
customer = order.billing = order.shipping = Customer.new
|
1476
|
+
|
1477
|
+
assert order.save
|
1478
|
+
order.reload
|
1479
|
+
|
1480
|
+
assert_equal customer, order.billing
|
1481
|
+
assert_equal customer, order.shipping
|
1482
|
+
|
1483
|
+
assert_equal num_orders +1, Order.count
|
1484
|
+
assert_equal num_customers +2, Customer.count
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
|
1488
|
+
def test_association_assignment_sticks
|
1489
|
+
post = Post.find(:first)
|
1490
|
+
|
1491
|
+
author1, author2 = Author.find(:all, :limit => 2)
|
1492
|
+
assert_not_nil author1
|
1493
|
+
assert_not_nil author2
|
1494
|
+
|
1495
|
+
# make sure the association is loaded
|
1496
|
+
post.author
|
1497
|
+
|
1498
|
+
# set the association by id, directly
|
1499
|
+
post.author_id = author2.id
|
1500
|
+
|
1501
|
+
# save and reload
|
1502
|
+
post.save!
|
1503
|
+
post.reload
|
1504
|
+
|
1505
|
+
# the author id of the post should be the id we set
|
1506
|
+
assert_equal post.author_id, author2.id
|
1507
|
+
end
|
1508
|
+
|
1509
|
+
end
|
1510
|
+
|
1511
|
+
|
1512
|
+
class ProjectWithAfterCreateHook < ActiveRecord::Base
|
1513
|
+
set_table_name 'projects'
|
1514
|
+
has_and_belongs_to_many :developers,
|
1515
|
+
:class_name => "DeveloperForProjectWithAfterCreateHook",
|
1516
|
+
:join_table => "developers_projects",
|
1517
|
+
:foreign_key => "project_id",
|
1518
|
+
:association_foreign_key => "developer_id"
|
1519
|
+
|
1520
|
+
after_create :add_david
|
1521
|
+
|
1522
|
+
def add_david
|
1523
|
+
david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
|
1524
|
+
david.projects << self
|
1525
|
+
end
|
1526
|
+
end
|
1527
|
+
|
1528
|
+
class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
|
1529
|
+
set_table_name 'developers'
|
1530
|
+
has_and_belongs_to_many :projects,
|
1531
|
+
:class_name => "ProjectWithAfterCreateHook",
|
1532
|
+
:join_table => "developers_projects",
|
1533
|
+
:association_foreign_key => "project_id",
|
1534
|
+
:foreign_key => "developer_id"
|
1535
|
+
end
|
1536
|
+
|
1537
|
+
|
1538
|
+
class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
1539
|
+
fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects
|
1540
|
+
|
1541
|
+
def test_has_and_belongs_to_many
|
1542
|
+
david = Developer.find(1)
|
1543
|
+
|
1544
|
+
assert !david.projects.empty?
|
1545
|
+
assert_equal 2, david.projects.size
|
1546
|
+
|
1547
|
+
active_record = Project.find(1)
|
1548
|
+
assert !active_record.developers.empty?
|
1549
|
+
assert_equal 3, active_record.developers.size
|
1550
|
+
assert active_record.developers.include?(david)
|
1551
|
+
end
|
1552
|
+
|
1553
|
+
def test_triple_equality
|
1554
|
+
assert !(Array === Developer.find(1).projects)
|
1555
|
+
assert Developer.find(1).projects === Array
|
1556
|
+
end
|
1557
|
+
|
1558
|
+
def test_adding_single
|
392
1559
|
jamis = Developer.find(2)
|
393
|
-
jamis.projects.
|
1560
|
+
jamis.projects.reload # causing the collection to load
|
394
1561
|
action_controller = Project.find(2)
|
395
1562
|
assert_equal 1, jamis.projects.size
|
396
|
-
assert_equal 1, action_controller.developers.size
|
397
|
-
|
1563
|
+
assert_equal 1, action_controller.developers.size
|
1564
|
+
|
398
1565
|
jamis.projects << action_controller
|
399
1566
|
|
400
1567
|
assert_equal 2, jamis.projects.size
|
@@ -404,74 +1571,570 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
404
1571
|
|
405
1572
|
def test_adding_type_mismatch
|
406
1573
|
jamis = Developer.find(2)
|
407
|
-
|
408
|
-
|
1574
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil }
|
1575
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 }
|
409
1576
|
end
|
410
1577
|
|
411
1578
|
def test_adding_from_the_project
|
412
1579
|
jamis = Developer.find(2)
|
413
1580
|
action_controller = Project.find(2)
|
414
|
-
action_controller.developers.
|
1581
|
+
action_controller.developers.reload
|
1582
|
+
assert_equal 1, jamis.projects.size
|
1583
|
+
assert_equal 1, action_controller.developers.size
|
1584
|
+
|
1585
|
+
action_controller.developers << jamis
|
1586
|
+
|
1587
|
+
assert_equal 2, jamis.projects(true).size
|
1588
|
+
assert_equal 2, action_controller.developers.size
|
1589
|
+
assert_equal 2, action_controller.developers(true).size
|
1590
|
+
end
|
1591
|
+
|
1592
|
+
def test_adding_from_the_project_fixed_timestamp
|
1593
|
+
jamis = Developer.find(2)
|
1594
|
+
action_controller = Project.find(2)
|
1595
|
+
action_controller.developers.reload
|
415
1596
|
assert_equal 1, jamis.projects.size
|
416
1597
|
assert_equal 1, action_controller.developers.size
|
1598
|
+
updated_at = jamis.updated_at
|
417
1599
|
|
418
|
-
action_controller.developers << jamis
|
419
|
-
|
1600
|
+
action_controller.developers << jamis
|
1601
|
+
|
1602
|
+
assert_equal updated_at, jamis.updated_at
|
420
1603
|
assert_equal 2, jamis.projects(true).size
|
421
1604
|
assert_equal 2, action_controller.developers.size
|
422
1605
|
assert_equal 2, action_controller.developers(true).size
|
423
1606
|
end
|
424
1607
|
|
1608
|
+
def test_adding_multiple
|
1609
|
+
aredridel = Developer.new("name" => "Aredridel")
|
1610
|
+
aredridel.save
|
1611
|
+
aredridel.projects.reload
|
1612
|
+
aredridel.projects.push(Project.find(1), Project.find(2))
|
1613
|
+
assert_equal 2, aredridel.projects.size
|
1614
|
+
assert_equal 2, aredridel.projects(true).size
|
1615
|
+
end
|
1616
|
+
|
425
1617
|
def test_adding_a_collection
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
assert_equal 2,
|
431
|
-
assert_equal 2,
|
1618
|
+
aredridel = Developer.new("name" => "Aredridel")
|
1619
|
+
aredridel.save
|
1620
|
+
aredridel.projects.reload
|
1621
|
+
aredridel.projects.concat([Project.find(1), Project.find(2)])
|
1622
|
+
assert_equal 2, aredridel.projects.size
|
1623
|
+
assert_equal 2, aredridel.projects(true).size
|
432
1624
|
end
|
433
|
-
|
1625
|
+
|
1626
|
+
def test_adding_uses_default_values_on_join_table
|
1627
|
+
ac = projects(:action_controller)
|
1628
|
+
assert !developers(:jamis).projects.include?(ac)
|
1629
|
+
developers(:jamis).projects << ac
|
1630
|
+
|
1631
|
+
assert developers(:jamis, :reload).projects.include?(ac)
|
1632
|
+
project = developers(:jamis).projects.detect { |p| p == ac }
|
1633
|
+
assert_equal 1, project.access_level.to_i
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
def test_habtm_attribute_access_and_respond_to
|
1637
|
+
project = developers(:jamis).projects[0]
|
1638
|
+
assert project.has_attribute?("name")
|
1639
|
+
assert project.has_attribute?("joined_on")
|
1640
|
+
assert project.has_attribute?("access_level")
|
1641
|
+
assert project.respond_to?("name")
|
1642
|
+
assert project.respond_to?("name=")
|
1643
|
+
assert project.respond_to?("name?")
|
1644
|
+
assert project.respond_to?("joined_on")
|
1645
|
+
# given that the 'join attribute' won't be persisted, I don't
|
1646
|
+
# think we should define the mutators
|
1647
|
+
#assert project.respond_to?("joined_on=")
|
1648
|
+
assert project.respond_to?("joined_on?")
|
1649
|
+
assert project.respond_to?("access_level")
|
1650
|
+
#assert project.respond_to?("access_level=")
|
1651
|
+
assert project.respond_to?("access_level?")
|
1652
|
+
end
|
1653
|
+
|
1654
|
+
def test_habtm_adding_before_save
|
1655
|
+
no_of_devels = Developer.count
|
1656
|
+
no_of_projects = Project.count
|
1657
|
+
aredridel = Developer.new("name" => "Aredridel")
|
1658
|
+
aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
|
1659
|
+
assert aredridel.new_record?
|
1660
|
+
assert p.new_record?
|
1661
|
+
assert aredridel.save
|
1662
|
+
assert !aredridel.new_record?
|
1663
|
+
assert_equal no_of_devels+1, Developer.count
|
1664
|
+
assert_equal no_of_projects+1, Project.count
|
1665
|
+
assert_equal 2, aredridel.projects.size
|
1666
|
+
assert_equal 2, aredridel.projects(true).size
|
1667
|
+
end
|
1668
|
+
|
1669
|
+
def test_habtm_saving_multiple_relationships
|
1670
|
+
new_project = Project.new("name" => "Grimetime")
|
1671
|
+
amount_of_developers = 4
|
1672
|
+
developers = (0...amount_of_developers).collect {|i| Developer.create(:name => "JME #{i}") }.reverse
|
1673
|
+
|
1674
|
+
new_project.developer_ids = [developers[0].id, developers[1].id]
|
1675
|
+
new_project.developers_with_callback_ids = [developers[2].id, developers[3].id]
|
1676
|
+
assert new_project.save
|
1677
|
+
|
1678
|
+
new_project.reload
|
1679
|
+
assert_equal amount_of_developers, new_project.developers.size
|
1680
|
+
assert_equal developers, new_project.developers
|
1681
|
+
end
|
1682
|
+
|
1683
|
+
def test_habtm_unique_order_preserved
|
1684
|
+
assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).non_unique_developers
|
1685
|
+
assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).developers
|
1686
|
+
end
|
1687
|
+
|
1688
|
+
def test_build
|
1689
|
+
devel = Developer.find(1)
|
1690
|
+
proj = devel.projects.build("name" => "Projekt")
|
1691
|
+
assert_equal devel.projects.last, proj
|
1692
|
+
assert proj.new_record?
|
1693
|
+
devel.save
|
1694
|
+
assert !proj.new_record?
|
1695
|
+
assert_equal devel.projects.last, proj
|
1696
|
+
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
1697
|
+
end
|
1698
|
+
|
1699
|
+
def test_build_by_new_record
|
1700
|
+
devel = Developer.new(:name => "Marcel", :salary => 75000)
|
1701
|
+
proj1 = devel.projects.build(:name => "Make bed")
|
1702
|
+
proj2 = devel.projects.build(:name => "Lie in it")
|
1703
|
+
assert_equal devel.projects.last, proj2
|
1704
|
+
assert proj2.new_record?
|
1705
|
+
devel.save
|
1706
|
+
assert !devel.new_record?
|
1707
|
+
assert !proj2.new_record?
|
1708
|
+
assert_equal devel.projects.last, proj2
|
1709
|
+
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
|
1710
|
+
end
|
1711
|
+
|
1712
|
+
def test_create
|
1713
|
+
devel = Developer.find(1)
|
1714
|
+
proj = devel.projects.create("name" => "Projekt")
|
1715
|
+
assert_equal devel.projects.last, proj
|
1716
|
+
assert !proj.new_record?
|
1717
|
+
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
1718
|
+
end
|
1719
|
+
|
1720
|
+
def test_create_by_new_record
|
1721
|
+
devel = Developer.new(:name => "Marcel", :salary => 75000)
|
1722
|
+
proj1 = devel.projects.build(:name => "Make bed")
|
1723
|
+
proj2 = devel.projects.build(:name => "Lie in it")
|
1724
|
+
assert_equal devel.projects.last, proj2
|
1725
|
+
assert proj2.new_record?
|
1726
|
+
devel.save
|
1727
|
+
assert !devel.new_record?
|
1728
|
+
assert !proj2.new_record?
|
1729
|
+
assert_equal devel.projects.last, proj2
|
1730
|
+
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
|
1731
|
+
end
|
1732
|
+
|
1733
|
+
def test_uniq_after_the_fact
|
1734
|
+
developers(:jamis).projects << projects(:active_record)
|
1735
|
+
developers(:jamis).projects << projects(:active_record)
|
1736
|
+
assert_equal 3, developers(:jamis).projects.size
|
1737
|
+
assert_equal 1, developers(:jamis).projects.uniq.size
|
1738
|
+
end
|
1739
|
+
|
1740
|
+
def test_uniq_before_the_fact
|
1741
|
+
projects(:active_record).developers << developers(:jamis)
|
1742
|
+
projects(:active_record).developers << developers(:david)
|
1743
|
+
assert_equal 3, projects(:active_record, :reload).developers.size
|
1744
|
+
end
|
1745
|
+
|
434
1746
|
def test_deleting
|
435
1747
|
david = Developer.find(1)
|
436
1748
|
active_record = Project.find(1)
|
437
|
-
david.projects.
|
1749
|
+
david.projects.reload
|
438
1750
|
assert_equal 2, david.projects.size
|
439
|
-
assert_equal
|
1751
|
+
assert_equal 3, active_record.developers.size
|
440
1752
|
|
441
1753
|
david.projects.delete(active_record)
|
442
|
-
|
1754
|
+
|
443
1755
|
assert_equal 1, david.projects.size
|
444
1756
|
assert_equal 1, david.projects(true).size
|
445
|
-
assert_equal
|
1757
|
+
assert_equal 2, active_record.developers(true).size
|
446
1758
|
end
|
447
1759
|
|
448
|
-
def
|
1760
|
+
def test_deleting_array
|
449
1761
|
david = Developer.find(1)
|
450
|
-
david.projects.
|
451
|
-
david.projects.delete(Project.
|
1762
|
+
david.projects.reload
|
1763
|
+
david.projects.delete(Project.find(:all))
|
452
1764
|
assert_equal 0, david.projects.size
|
453
1765
|
assert_equal 0, david.projects(true).size
|
454
1766
|
end
|
455
|
-
|
456
|
-
def
|
1767
|
+
|
1768
|
+
def test_deleting_with_sql
|
1769
|
+
david = Developer.find(1)
|
1770
|
+
active_record = Project.find(1)
|
1771
|
+
active_record.developers.reload
|
1772
|
+
assert_equal 3, active_record.developers_by_sql.size
|
1773
|
+
|
1774
|
+
active_record.developers_by_sql.delete(david)
|
1775
|
+
assert_equal 2, active_record.developers_by_sql(true).size
|
1776
|
+
end
|
1777
|
+
|
1778
|
+
def test_deleting_array_with_sql
|
1779
|
+
active_record = Project.find(1)
|
1780
|
+
active_record.developers.reload
|
1781
|
+
assert_equal 3, active_record.developers_by_sql.size
|
1782
|
+
|
1783
|
+
active_record.developers_by_sql.delete(Developer.find(:all))
|
1784
|
+
assert_equal 0, active_record.developers_by_sql(true).size
|
1785
|
+
end
|
1786
|
+
|
1787
|
+
def test_deleting_all
|
457
1788
|
david = Developer.find(1)
|
458
|
-
david.projects.
|
459
|
-
david.projects.
|
1789
|
+
david.projects.reload
|
1790
|
+
david.projects.clear
|
460
1791
|
assert_equal 0, david.projects.size
|
461
1792
|
assert_equal 0, david.projects(true).size
|
462
1793
|
end
|
463
1794
|
|
464
1795
|
def test_removing_associations_on_destroy
|
465
|
-
|
466
|
-
assert
|
1796
|
+
david = DeveloperWithBeforeDestroyRaise.find(1)
|
1797
|
+
assert !david.projects.empty?
|
1798
|
+
assert_nothing_raised { david.destroy }
|
1799
|
+
assert david.projects.empty?
|
1800
|
+
assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty?
|
467
1801
|
end
|
468
|
-
|
1802
|
+
|
1803
|
+
def test_additional_columns_from_join_table
|
1804
|
+
assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on.to_date
|
1805
|
+
end
|
1806
|
+
|
469
1807
|
def test_destroy_all
|
470
1808
|
david = Developer.find(1)
|
471
|
-
david.projects.
|
1809
|
+
david.projects.reload
|
472
1810
|
assert !david.projects.empty?
|
473
1811
|
david.projects.destroy_all
|
474
1812
|
assert david.projects.empty?
|
475
1813
|
assert david.projects(true).empty?
|
476
1814
|
end
|
477
|
-
|
1815
|
+
|
1816
|
+
def test_deprecated_push_with_attributes_was_removed
|
1817
|
+
jamis = developers(:jamis)
|
1818
|
+
assert_raise(NoMethodError) do
|
1819
|
+
jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today)
|
1820
|
+
end
|
1821
|
+
end
|
1822
|
+
|
1823
|
+
def test_associations_with_conditions
|
1824
|
+
assert_equal 3, projects(:active_record).developers.size
|
1825
|
+
assert_equal 1, projects(:active_record).developers_named_david.size
|
1826
|
+
assert_equal 1, projects(:active_record).developers_named_david_with_hash_conditions.size
|
1827
|
+
|
1828
|
+
assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id)
|
1829
|
+
assert_equal developers(:david), projects(:active_record).developers_named_david_with_hash_conditions.find(developers(:david).id)
|
1830
|
+
assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id)
|
1831
|
+
|
1832
|
+
projects(:active_record).developers_named_david.clear
|
1833
|
+
assert_equal 2, projects(:active_record, :reload).developers.size
|
1834
|
+
end
|
1835
|
+
|
1836
|
+
def test_find_in_association
|
1837
|
+
# Using sql
|
1838
|
+
assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find"
|
1839
|
+
|
1840
|
+
# Using ruby
|
1841
|
+
active_record = projects(:active_record)
|
1842
|
+
active_record.developers.reload
|
1843
|
+
assert_equal developers(:david), active_record.developers.find(developers(:david).id), "Ruby find"
|
1844
|
+
end
|
1845
|
+
|
1846
|
+
def test_find_in_association_with_custom_finder_sql
|
1847
|
+
assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id), "SQL find"
|
1848
|
+
|
1849
|
+
active_record = projects(:active_record)
|
1850
|
+
active_record.developers_with_finder_sql.reload
|
1851
|
+
assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find"
|
1852
|
+
end
|
1853
|
+
|
1854
|
+
def test_find_in_association_with_custom_finder_sql_and_string_id
|
1855
|
+
assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id.to_s), "SQL find"
|
1856
|
+
end
|
1857
|
+
|
1858
|
+
def test_find_with_merged_options
|
1859
|
+
assert_equal 1, projects(:active_record).limited_developers.size
|
1860
|
+
assert_equal 1, projects(:active_record).limited_developers.find(:all).size
|
1861
|
+
assert_equal 3, projects(:active_record).limited_developers.find(:all, :limit => nil).size
|
1862
|
+
end
|
1863
|
+
|
1864
|
+
def test_dynamic_find_should_respect_association_order
|
1865
|
+
# Developers are ordered 'name DESC, id DESC'
|
1866
|
+
low_id_jamis = developers(:jamis)
|
1867
|
+
middle_id_jamis = developers(:poor_jamis)
|
1868
|
+
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
|
1869
|
+
|
1870
|
+
assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'")
|
1871
|
+
assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis')
|
1872
|
+
end
|
1873
|
+
|
1874
|
+
def test_dynamic_find_order_should_override_association_order
|
1875
|
+
# Developers are ordered 'name DESC, id DESC'
|
1876
|
+
low_id_jamis = developers(:jamis)
|
1877
|
+
middle_id_jamis = developers(:poor_jamis)
|
1878
|
+
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
|
1879
|
+
|
1880
|
+
assert_equal low_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'", :order => 'id')
|
1881
|
+
assert_equal low_id_jamis, projects(:active_record).developers.find_by_name('Jamis', :order => 'id')
|
1882
|
+
end
|
1883
|
+
|
1884
|
+
def test_dynamic_find_all_should_respect_association_order
|
1885
|
+
# Developers are ordered 'name DESC, id DESC'
|
1886
|
+
low_id_jamis = developers(:jamis)
|
1887
|
+
middle_id_jamis = developers(:poor_jamis)
|
1888
|
+
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
|
1889
|
+
|
1890
|
+
assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'")
|
1891
|
+
assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis')
|
1892
|
+
end
|
1893
|
+
|
1894
|
+
def test_dynamic_find_all_order_should_override_association_order
|
1895
|
+
# Developers are ordered 'name DESC, id DESC'
|
1896
|
+
low_id_jamis = developers(:jamis)
|
1897
|
+
middle_id_jamis = developers(:poor_jamis)
|
1898
|
+
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
|
1899
|
+
|
1900
|
+
assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'", :order => 'id')
|
1901
|
+
assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis', :order => 'id')
|
1902
|
+
end
|
1903
|
+
|
1904
|
+
def test_dynamic_find_all_should_respect_association_limit
|
1905
|
+
assert_equal 1, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'").length
|
1906
|
+
assert_equal 1, projects(:active_record).limited_developers.find_all_by_name('Jamis').length
|
1907
|
+
end
|
1908
|
+
|
1909
|
+
def test_dynamic_find_all_order_should_override_association_limit
|
1910
|
+
assert_equal 2, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'", :limit => 9_000).length
|
1911
|
+
assert_equal 2, projects(:active_record).limited_developers.find_all_by_name('Jamis', :limit => 9_000).length
|
1912
|
+
end
|
1913
|
+
|
1914
|
+
def test_new_with_values_in_collection
|
1915
|
+
jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis')
|
1916
|
+
david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
|
1917
|
+
project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie")
|
1918
|
+
project.developers << jamis
|
1919
|
+
project.save!
|
1920
|
+
project.reload
|
1921
|
+
|
1922
|
+
assert project.developers.include?(jamis)
|
1923
|
+
assert project.developers.include?(david)
|
1924
|
+
end
|
1925
|
+
|
1926
|
+
def test_find_in_association_with_options
|
1927
|
+
developers = projects(:active_record).developers.find(:all)
|
1928
|
+
assert_equal 3, developers.size
|
1929
|
+
|
1930
|
+
assert_equal developers(:poor_jamis), projects(:active_record).developers.find(:first, :conditions => "salary < 10000")
|
1931
|
+
assert_equal developers(:jamis), projects(:active_record).developers.find(:first, :order => "salary DESC")
|
1932
|
+
end
|
1933
|
+
|
1934
|
+
def test_replace_with_less
|
1935
|
+
david = developers(:david)
|
1936
|
+
david.projects = [projects(:action_controller)]
|
1937
|
+
assert david.save
|
1938
|
+
assert_equal 1, david.projects.length
|
1939
|
+
end
|
1940
|
+
|
1941
|
+
def test_replace_with_new
|
1942
|
+
david = developers(:david)
|
1943
|
+
david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
|
1944
|
+
david.save
|
1945
|
+
assert_equal 2, david.projects.length
|
1946
|
+
assert !david.projects.include?(projects(:active_record))
|
1947
|
+
end
|
1948
|
+
|
1949
|
+
def test_replace_on_new_object
|
1950
|
+
new_developer = Developer.new("name" => "Matz")
|
1951
|
+
new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
|
1952
|
+
new_developer.save
|
1953
|
+
assert_equal 2, new_developer.projects.length
|
1954
|
+
end
|
1955
|
+
|
1956
|
+
def test_consider_type
|
1957
|
+
developer = Developer.find(:first)
|
1958
|
+
special_project = SpecialProject.create("name" => "Special Project")
|
1959
|
+
|
1960
|
+
other_project = developer.projects.first
|
1961
|
+
developer.special_projects << special_project
|
1962
|
+
developer.reload
|
1963
|
+
|
1964
|
+
assert developer.projects.include?(special_project)
|
1965
|
+
assert developer.special_projects.include?(special_project)
|
1966
|
+
assert !developer.special_projects.include?(other_project)
|
1967
|
+
end
|
1968
|
+
|
1969
|
+
def test_update_attributes_after_push_without_duplicate_join_table_rows
|
1970
|
+
developer = Developer.new("name" => "Kano")
|
1971
|
+
project = SpecialProject.create("name" => "Special Project")
|
1972
|
+
assert developer.save
|
1973
|
+
developer.projects << project
|
1974
|
+
developer.update_attribute("name", "Bruza")
|
1975
|
+
assert_equal 1, Developer.connection.select_value(<<-end_sql).to_i
|
1976
|
+
SELECT count(*) FROM developers_projects
|
1977
|
+
WHERE project_id = #{project.id}
|
1978
|
+
AND developer_id = #{developer.id}
|
1979
|
+
end_sql
|
1980
|
+
end
|
1981
|
+
|
1982
|
+
def test_updating_attributes_on_non_rich_associations
|
1983
|
+
welcome = categories(:technology).posts.first
|
1984
|
+
welcome.title = "Something else"
|
1985
|
+
assert welcome.save!
|
1986
|
+
end
|
1987
|
+
|
1988
|
+
def test_habtm_respects_select
|
1989
|
+
categories(:technology).select_testing_posts(true).each do |o|
|
1990
|
+
assert_respond_to o, :correctness_marker
|
1991
|
+
end
|
1992
|
+
assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker
|
1993
|
+
end
|
1994
|
+
|
1995
|
+
def test_updating_attributes_on_rich_associations
|
1996
|
+
david = projects(:action_controller).developers.first
|
1997
|
+
david.name = "DHH"
|
1998
|
+
assert_raises(ActiveRecord::ReadOnlyRecord) { david.save! }
|
1999
|
+
end
|
2000
|
+
|
2001
|
+
def test_updating_attributes_on_rich_associations_with_limited_find_from_reflection
|
2002
|
+
david = projects(:action_controller).selected_developers.first
|
2003
|
+
david.name = "DHH"
|
2004
|
+
assert_nothing_raised { david.save! }
|
2005
|
+
end
|
2006
|
+
|
2007
|
+
|
2008
|
+
def test_updating_attributes_on_rich_associations_with_limited_find
|
2009
|
+
david = projects(:action_controller).developers.find(:all, :select => "developers.*").first
|
2010
|
+
david.name = "DHH"
|
2011
|
+
assert david.save!
|
2012
|
+
end
|
2013
|
+
|
2014
|
+
def test_join_table_alias
|
2015
|
+
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size
|
2016
|
+
end
|
2017
|
+
|
2018
|
+
def test_join_with_group
|
2019
|
+
group = Developer.columns.inject([]) do |g, c|
|
2020
|
+
g << "developers.#{c.name}"
|
2021
|
+
g << "developers_projects_2.#{c.name}"
|
2022
|
+
end
|
2023
|
+
Project.columns.each { |c| group << "projects.#{c.name}" }
|
2024
|
+
|
2025
|
+
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group.join(",")).size
|
2026
|
+
end
|
2027
|
+
|
2028
|
+
def test_get_ids
|
2029
|
+
assert_equal projects(:active_record, :action_controller).map(&:id), developers(:david).project_ids
|
2030
|
+
assert_equal [projects(:active_record).id], developers(:jamis).project_ids
|
2031
|
+
end
|
2032
|
+
|
2033
|
+
def test_assign_ids
|
2034
|
+
developer = Developer.new("name" => "Joe")
|
2035
|
+
developer.project_ids = projects(:active_record, :action_controller).map(&:id)
|
2036
|
+
developer.save
|
2037
|
+
developer.reload
|
2038
|
+
assert_equal 2, developer.projects.length
|
2039
|
+
assert_equal projects(:active_record), developer.projects[0]
|
2040
|
+
assert_equal projects(:action_controller), developer.projects[1]
|
2041
|
+
end
|
2042
|
+
|
2043
|
+
def test_assign_ids_ignoring_blanks
|
2044
|
+
developer = Developer.new("name" => "Joe")
|
2045
|
+
developer.project_ids = [projects(:active_record).id, nil, projects(:action_controller).id, '']
|
2046
|
+
developer.save
|
2047
|
+
developer.reload
|
2048
|
+
assert_equal 2, developer.projects.length
|
2049
|
+
assert_equal projects(:active_record), developer.projects[0]
|
2050
|
+
assert_equal projects(:action_controller), developer.projects[1]
|
2051
|
+
end
|
2052
|
+
|
2053
|
+
def test_select_limited_ids_list
|
2054
|
+
# Set timestamps
|
2055
|
+
Developer.transaction do
|
2056
|
+
Developer.find(:all, :order => 'id').each_with_index do |record, i|
|
2057
|
+
record.update_attributes(:created_at => 5.years.ago + (i * 5.minutes))
|
2058
|
+
end
|
2059
|
+
end
|
2060
|
+
|
2061
|
+
join_base = ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase.new(Project)
|
2062
|
+
join_dep = ActiveRecord::Associations::ClassMethods::JoinDependency.new(join_base, :developers, nil)
|
2063
|
+
projects = Project.send(:select_limited_ids_list, {:order => 'developers.created_at'}, join_dep)
|
2064
|
+
assert !projects.include?("'"), projects
|
2065
|
+
assert_equal %w(1 2), projects.scan(/\d/).sort
|
2066
|
+
end
|
2067
|
+
|
2068
|
+
def test_scoped_find_on_through_association_doesnt_return_read_only_records
|
2069
|
+
tag = Post.find(1).tags.find_by_name("General")
|
2070
|
+
|
2071
|
+
assert_nothing_raised do
|
2072
|
+
tag.save!
|
2073
|
+
end
|
2074
|
+
end
|
2075
|
+
end
|
2076
|
+
|
2077
|
+
|
2078
|
+
class OverridingAssociationsTest < Test::Unit::TestCase
|
2079
|
+
class Person < ActiveRecord::Base; end
|
2080
|
+
class DifferentPerson < ActiveRecord::Base; end
|
2081
|
+
|
2082
|
+
class PeopleList < ActiveRecord::Base
|
2083
|
+
has_and_belongs_to_many :has_and_belongs_to_many, :before_add => :enlist
|
2084
|
+
has_many :has_many, :before_add => :enlist
|
2085
|
+
belongs_to :belongs_to
|
2086
|
+
has_one :has_one
|
2087
|
+
end
|
2088
|
+
|
2089
|
+
class DifferentPeopleList < PeopleList
|
2090
|
+
# Different association with the same name, callbacks should be omitted here.
|
2091
|
+
has_and_belongs_to_many :has_and_belongs_to_many, :class_name => 'DifferentPerson'
|
2092
|
+
has_many :has_many, :class_name => 'DifferentPerson'
|
2093
|
+
belongs_to :belongs_to, :class_name => 'DifferentPerson'
|
2094
|
+
has_one :has_one, :class_name => 'DifferentPerson'
|
2095
|
+
end
|
2096
|
+
|
2097
|
+
def test_habtm_association_redefinition_callbacks_should_differ_and_not_inherited
|
2098
|
+
# redeclared association on AR descendant should not inherit callbacks from superclass
|
2099
|
+
callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
|
2100
|
+
assert_equal([:enlist], callbacks)
|
2101
|
+
callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
|
2102
|
+
assert_equal([], callbacks)
|
2103
|
+
end
|
2104
|
+
|
2105
|
+
def test_has_many_association_redefinition_callbacks_should_differ_and_not_inherited
|
2106
|
+
# redeclared association on AR descendant should not inherit callbacks from superclass
|
2107
|
+
callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_many)
|
2108
|
+
assert_equal([:enlist], callbacks)
|
2109
|
+
callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_many)
|
2110
|
+
assert_equal([], callbacks)
|
2111
|
+
end
|
2112
|
+
|
2113
|
+
def test_habtm_association_redefinition_reflections_should_differ_and_not_inherited
|
2114
|
+
assert_not_equal(
|
2115
|
+
PeopleList.reflect_on_association(:has_and_belongs_to_many),
|
2116
|
+
DifferentPeopleList.reflect_on_association(:has_and_belongs_to_many)
|
2117
|
+
)
|
2118
|
+
end
|
2119
|
+
|
2120
|
+
def test_has_many_association_redefinition_reflections_should_differ_and_not_inherited
|
2121
|
+
assert_not_equal(
|
2122
|
+
PeopleList.reflect_on_association(:has_many),
|
2123
|
+
DifferentPeopleList.reflect_on_association(:has_many)
|
2124
|
+
)
|
2125
|
+
end
|
2126
|
+
|
2127
|
+
def test_belongs_to_association_redefinition_reflections_should_differ_and_not_inherited
|
2128
|
+
assert_not_equal(
|
2129
|
+
PeopleList.reflect_on_association(:belongs_to),
|
2130
|
+
DifferentPeopleList.reflect_on_association(:belongs_to)
|
2131
|
+
)
|
2132
|
+
end
|
2133
|
+
|
2134
|
+
def test_has_one_association_redefinition_reflections_should_differ_and_not_inherited
|
2135
|
+
assert_not_equal(
|
2136
|
+
PeopleList.reflect_on_association(:has_one),
|
2137
|
+
DifferentPeopleList.reflect_on_association(:has_one)
|
2138
|
+
)
|
2139
|
+
end
|
2140
|
+
end
|