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
@@ -0,0 +1,442 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/post'
|
3
|
+
require 'fixtures/comment'
|
4
|
+
require 'fixtures/author'
|
5
|
+
require 'fixtures/category'
|
6
|
+
require 'fixtures/company'
|
7
|
+
require 'fixtures/person'
|
8
|
+
require 'fixtures/reader'
|
9
|
+
|
10
|
+
class EagerAssociationTest < Test::Unit::TestCase
|
11
|
+
fixtures :posts, :comments, :authors, :categories, :categories_posts,
|
12
|
+
:companies, :accounts, :tags, :people, :readers
|
13
|
+
|
14
|
+
def test_loading_with_one_association
|
15
|
+
posts = Post.find(:all, :include => :comments)
|
16
|
+
post = posts.find { |p| p.id == 1 }
|
17
|
+
assert_equal 2, post.comments.size
|
18
|
+
assert post.comments.include?(comments(:greetings))
|
19
|
+
|
20
|
+
post = Post.find(:first, :include => :comments, :conditions => "posts.title = 'Welcome to the weblog'")
|
21
|
+
assert_equal 2, post.comments.size
|
22
|
+
assert post.comments.include?(comments(:greetings))
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_loading_conditions_with_or
|
26
|
+
posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'")
|
27
|
+
assert_nil posts.detect { |p| p.author_id != authors(:david).id },
|
28
|
+
"expected to find only david's posts"
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_with_ordering
|
32
|
+
list = Post.find(:all, :include => :comments, :order => "posts.id DESC")
|
33
|
+
[:eager_other, :sti_habtm, :sti_post_and_comments, :sti_comments,
|
34
|
+
:authorless, :thinking, :welcome
|
35
|
+
].each_with_index do |post, index|
|
36
|
+
assert_equal posts(post), list[index]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_with_two_tables_in_from_without_getting_double_quoted
|
41
|
+
posts = Post.find(:all,
|
42
|
+
:select => "posts.*",
|
43
|
+
:from => "authors, posts",
|
44
|
+
:include => :comments,
|
45
|
+
:conditions => "posts.author_id = authors.id",
|
46
|
+
:order => "posts.id"
|
47
|
+
)
|
48
|
+
|
49
|
+
assert_equal 2, posts.first.comments.size
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_loading_with_multiple_associations
|
53
|
+
posts = Post.find(:all, :include => [ :comments, :author, :categories ], :order => "posts.id")
|
54
|
+
assert_equal 2, posts.first.comments.size
|
55
|
+
assert_equal 2, posts.first.categories.size
|
56
|
+
assert posts.first.comments.include?(comments(:greetings))
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_loading_from_an_association
|
60
|
+
posts = authors(:david).posts.find(:all, :include => :comments, :order => "posts.id")
|
61
|
+
assert_equal 2, posts.first.comments.size
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_loading_with_no_associations
|
65
|
+
assert_nil Post.find(posts(:authorless).id, :include => :author).author
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_eager_association_loading_with_belongs_to
|
69
|
+
comments = Comment.find(:all, :include => :post)
|
70
|
+
assert_equal 10, comments.length
|
71
|
+
titles = comments.map { |c| c.post.title }
|
72
|
+
assert titles.include?(posts(:welcome).title)
|
73
|
+
assert titles.include?(posts(:sti_post_and_comments).title)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_eager_association_loading_with_belongs_to_and_limit
|
77
|
+
comments = Comment.find(:all, :include => :post, :limit => 5, :order => 'comments.id')
|
78
|
+
assert_equal 5, comments.length
|
79
|
+
assert_equal [1,2,3,5,6], comments.collect { |c| c.id }
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_conditions
|
83
|
+
comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :order => 'comments.id')
|
84
|
+
assert_equal 3, comments.length
|
85
|
+
assert_equal [5,6,7], comments.collect { |c| c.id }
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset
|
89
|
+
comments = Comment.find(:all, :include => :post, :limit => 3, :offset => 2, :order => 'comments.id')
|
90
|
+
assert_equal 3, comments.length
|
91
|
+
assert_equal [3,5,6], comments.collect { |c| c.id }
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions
|
95
|
+
comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :offset => 1, :order => 'comments.id')
|
96
|
+
assert_equal 3, comments.length
|
97
|
+
assert_equal [6,7,8], comments.collect { |c| c.id }
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions_array
|
101
|
+
comments = Comment.find(:all, :include => :post, :conditions => ['post_id = ?',4], :limit => 3, :offset => 1, :order => 'comments.id')
|
102
|
+
assert_equal 3, comments.length
|
103
|
+
assert_equal [6,7,8], comments.collect { |c| c.id }
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_multiple_associations
|
107
|
+
posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :order => 'posts.id')
|
108
|
+
assert_equal 1, posts.length
|
109
|
+
assert_equal [1], posts.collect { |p| p.id }
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_multiple_associations
|
113
|
+
posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :offset => 1, :order => 'posts.id')
|
114
|
+
assert_equal 1, posts.length
|
115
|
+
assert_equal [2], posts.collect { |p| p.id }
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_eager_association_loading_with_explicit_join
|
119
|
+
posts = Post.find(:all, :include => :comments, :joins => "INNER JOIN authors ON posts.author_id = authors.id AND authors.name = 'Mary'", :limit => 1, :order => 'author_id')
|
120
|
+
assert_equal 1, posts.length
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_eager_with_has_many_through
|
124
|
+
posts_with_comments = people(:michael).posts.find(:all, :include => :comments)
|
125
|
+
posts_with_author = people(:michael).posts.find(:all, :include => :author )
|
126
|
+
posts_with_comments_and_author = people(:michael).posts.find(:all, :include => [ :comments, :author ])
|
127
|
+
assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum += post.comments.size }
|
128
|
+
assert_equal authors(:david), assert_no_queries { posts_with_author.first.author }
|
129
|
+
assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author }
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_eager_with_has_many_through_an_sti_join_model
|
133
|
+
author = Author.find(:first, :include => :special_post_comments, :order => 'authors.id')
|
134
|
+
assert_equal [comments(:does_it_hurt)], assert_no_queries { author.special_post_comments }
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_eager_with_has_many_through_an_sti_join_model_with_conditions_on_both
|
138
|
+
author = Author.find(:first, :include => :special_nonexistant_post_comments, :order => 'authors.id')
|
139
|
+
assert_equal [], author.special_nonexistant_post_comments
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_eager_with_has_many_through_join_model_with_conditions
|
143
|
+
assert_equal Author.find(:first, :include => :hello_post_comments,
|
144
|
+
:order => 'authors.id').hello_post_comments.sort_by(&:id),
|
145
|
+
Author.find(:first, :order => 'authors.id').hello_post_comments.sort_by(&:id)
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_eager_with_has_many_and_limit
|
149
|
+
posts = Post.find(:all, :order => 'posts.id asc', :include => [ :author, :comments ], :limit => 2)
|
150
|
+
assert_equal 2, posts.size
|
151
|
+
assert_equal 3, posts.inject(0) { |sum, post| sum += post.comments.size }
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_eager_with_has_many_and_limit_and_conditions
|
155
|
+
if current_adapter?(:OpenBaseAdapter)
|
156
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "FETCHBLOB(posts.body) = 'hello'", :order => "posts.id")
|
157
|
+
else
|
158
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.body = 'hello'", :order => "posts.id")
|
159
|
+
end
|
160
|
+
assert_equal 2, posts.size
|
161
|
+
assert_equal [4,5], posts.collect { |p| p.id }
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_eager_with_has_many_and_limit_and_conditions_array
|
165
|
+
if current_adapter?(:OpenBaseAdapter)
|
166
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "FETCHBLOB(posts.body) = ?", 'hello' ], :order => "posts.id")
|
167
|
+
else
|
168
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "posts.body = ?", 'hello' ], :order => "posts.id")
|
169
|
+
end
|
170
|
+
assert_equal 2, posts.size
|
171
|
+
assert_equal [4,5], posts.collect { |p| p.id }
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_eager_with_has_many_and_limit_and_conditions_array_on_the_eagers
|
175
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
|
176
|
+
assert_equal 2, posts.size
|
177
|
+
|
178
|
+
count = Post.count(:include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
|
179
|
+
assert_equal count, posts.size
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_eager_with_has_many_and_limit_ond_high_offset
|
183
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
|
184
|
+
assert_equal 0, posts.size
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_count_eager_with_has_many_and_limit_ond_high_offset
|
188
|
+
posts = Post.count(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
|
189
|
+
assert_equal 0, posts
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_eager_with_has_many_and_limit_with_no_results
|
193
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.title = 'magic forest'")
|
194
|
+
assert_equal 0, posts.size
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_eager_count_performed_on_a_has_many_association_with_multi_table_conditional
|
198
|
+
author = authors(:david)
|
199
|
+
author_posts_without_comments = author.posts.select { |post| post.comments.blank? }
|
200
|
+
assert_equal author_posts_without_comments.size, author.posts.count(:all, :include => :comments, :conditions => 'comments.id is null')
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_eager_with_has_and_belongs_to_many_and_limit
|
204
|
+
posts = Post.find(:all, :include => :categories, :order => "posts.id", :limit => 3)
|
205
|
+
assert_equal 3, posts.size
|
206
|
+
assert_equal 2, posts[0].categories.size
|
207
|
+
assert_equal 1, posts[1].categories.size
|
208
|
+
assert_equal 0, posts[2].categories.size
|
209
|
+
assert posts[0].categories.include?(categories(:technology))
|
210
|
+
assert posts[1].categories.include?(categories(:general))
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers
|
214
|
+
posts = authors(:david).posts.find(:all,
|
215
|
+
:include => :comments,
|
216
|
+
:conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
|
217
|
+
:limit => 2
|
218
|
+
)
|
219
|
+
assert_equal 2, posts.size
|
220
|
+
|
221
|
+
count = Post.count(
|
222
|
+
:include => [ :comments, :author ],
|
223
|
+
:conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
|
224
|
+
:limit => 2
|
225
|
+
)
|
226
|
+
assert_equal count, posts.size
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_eager_with_has_many_and_limit_and_scoped_conditions_on_the_eagers
|
230
|
+
posts = nil
|
231
|
+
Post.with_scope(:find => {
|
232
|
+
:include => :comments,
|
233
|
+
:conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'"
|
234
|
+
}) do
|
235
|
+
posts = authors(:david).posts.find(:all, :limit => 2)
|
236
|
+
assert_equal 2, posts.size
|
237
|
+
end
|
238
|
+
|
239
|
+
Post.with_scope(:find => {
|
240
|
+
:include => [ :comments, :author ],
|
241
|
+
:conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')"
|
242
|
+
}) do
|
243
|
+
count = Post.count(:limit => 2)
|
244
|
+
assert_equal count, posts.size
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_eager_with_has_many_and_limit_and_scoped_and_explicit_conditions_on_the_eagers
|
249
|
+
Post.with_scope(:find => { :conditions => "1=1" }) do
|
250
|
+
posts = authors(:david).posts.find(:all,
|
251
|
+
:include => :comments,
|
252
|
+
:conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
|
253
|
+
:limit => 2
|
254
|
+
)
|
255
|
+
assert_equal 2, posts.size
|
256
|
+
|
257
|
+
count = Post.count(
|
258
|
+
:include => [ :comments, :author ],
|
259
|
+
:conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
|
260
|
+
:limit => 2
|
261
|
+
)
|
262
|
+
assert_equal count, posts.size
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_eager_with_scoped_order_using_association_limiting_without_explicit_scope
|
267
|
+
posts_with_explicit_order = Post.find(:all, :conditions => 'comments.id is not null', :include => :comments, :order => 'posts.id DESC', :limit => 2)
|
268
|
+
posts_with_scoped_order = Post.with_scope(:find => {:order => 'posts.id DESC'}) do
|
269
|
+
Post.find(:all, :conditions => 'comments.id is not null', :include => :comments, :limit => 2)
|
270
|
+
end
|
271
|
+
assert_equal posts_with_explicit_order, posts_with_scoped_order
|
272
|
+
end
|
273
|
+
|
274
|
+
def test_eager_association_loading_with_habtm
|
275
|
+
posts = Post.find(:all, :include => :categories, :order => "posts.id")
|
276
|
+
assert_equal 2, posts[0].categories.size
|
277
|
+
assert_equal 1, posts[1].categories.size
|
278
|
+
assert_equal 0, posts[2].categories.size
|
279
|
+
assert posts[0].categories.include?(categories(:technology))
|
280
|
+
assert posts[1].categories.include?(categories(:general))
|
281
|
+
end
|
282
|
+
|
283
|
+
def test_eager_with_inheritance
|
284
|
+
posts = SpecialPost.find(:all, :include => [ :comments ])
|
285
|
+
end
|
286
|
+
|
287
|
+
def test_eager_has_one_with_association_inheritance
|
288
|
+
post = Post.find(4, :include => [ :very_special_comment ])
|
289
|
+
assert_equal "VerySpecialComment", post.very_special_comment.class.to_s
|
290
|
+
end
|
291
|
+
|
292
|
+
def test_eager_has_many_with_association_inheritance
|
293
|
+
post = Post.find(4, :include => [ :special_comments ])
|
294
|
+
post.special_comments.each do |special_comment|
|
295
|
+
assert_equal "SpecialComment", special_comment.class.to_s
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
def test_eager_habtm_with_association_inheritance
|
300
|
+
post = Post.find(6, :include => [ :special_categories ])
|
301
|
+
assert_equal 1, post.special_categories.size
|
302
|
+
post.special_categories.each do |special_category|
|
303
|
+
assert_equal "SpecialCategory", special_category.class.to_s
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_eager_with_has_one_dependent_does_not_destroy_dependent
|
308
|
+
assert_not_nil companies(:first_firm).account
|
309
|
+
f = Firm.find(:first, :include => :account,
|
310
|
+
:conditions => ["companies.name = ?", "37signals"])
|
311
|
+
assert_not_nil f.account
|
312
|
+
assert_equal companies(:first_firm, :reload).account, f.account
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_eager_with_multi_table_conditional_properly_counts_the_records_when_using_size
|
316
|
+
author = authors(:david)
|
317
|
+
posts_with_no_comments = author.posts.select { |post| post.comments.blank? }
|
318
|
+
assert_equal posts_with_no_comments.size, author.posts_with_no_comments.size
|
319
|
+
assert_equal posts_with_no_comments, author.posts_with_no_comments
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_eager_with_invalid_association_reference
|
323
|
+
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
324
|
+
post = Post.find(6, :include=> :monkeys )
|
325
|
+
}
|
326
|
+
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
327
|
+
post = Post.find(6, :include=>[ :monkeys ])
|
328
|
+
}
|
329
|
+
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
330
|
+
post = Post.find(6, :include=>[ 'monkeys' ])
|
331
|
+
}
|
332
|
+
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
|
333
|
+
post = Post.find(6, :include=>[ :monkeys, :elephants ])
|
334
|
+
}
|
335
|
+
end
|
336
|
+
|
337
|
+
def find_all_ordered(className, include=nil)
|
338
|
+
className.find(:all, :order=>"#{className.table_name}.#{className.primary_key}", :include=>include)
|
339
|
+
end
|
340
|
+
|
341
|
+
def test_limited_eager_with_order
|
342
|
+
assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title)', :limit => 2, :offset => 1)
|
343
|
+
assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1)
|
344
|
+
end
|
345
|
+
|
346
|
+
def test_limited_eager_with_multiple_order_columns
|
347
|
+
assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1)
|
348
|
+
assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_eager_with_multiple_associations_with_same_table_has_many_and_habtm
|
352
|
+
# Eager includes of has many and habtm associations aren't necessarily sorted in the same way
|
353
|
+
def assert_equal_after_sort(item1, item2, item3 = nil)
|
354
|
+
assert_equal(item1.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id})
|
355
|
+
assert_equal(item3.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id}) if item3
|
356
|
+
end
|
357
|
+
# Test regular association, association with conditions, association with
|
358
|
+
# STI, and association with conditions assured not to be true
|
359
|
+
post_types = [:posts, :other_posts, :special_posts]
|
360
|
+
# test both has_many and has_and_belongs_to_many
|
361
|
+
[Author, Category].each do |className|
|
362
|
+
d1 = find_all_ordered(className)
|
363
|
+
# test including all post types at once
|
364
|
+
d2 = find_all_ordered(className, post_types)
|
365
|
+
d1.each_index do |i|
|
366
|
+
assert_equal(d1[i], d2[i])
|
367
|
+
assert_equal_after_sort(d1[i].posts, d2[i].posts)
|
368
|
+
post_types[1..-1].each do |post_type|
|
369
|
+
# test including post_types together
|
370
|
+
d3 = find_all_ordered(className, [:posts, post_type])
|
371
|
+
assert_equal(d1[i], d3[i])
|
372
|
+
assert_equal_after_sort(d1[i].posts, d3[i].posts)
|
373
|
+
assert_equal_after_sort(d1[i].send(post_type), d2[i].send(post_type), d3[i].send(post_type))
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_eager_with_multiple_associations_with_same_table_has_one
|
380
|
+
d1 = find_all_ordered(Firm)
|
381
|
+
d2 = find_all_ordered(Firm, :account)
|
382
|
+
d1.each_index do |i|
|
383
|
+
assert_equal(d1[i], d2[i])
|
384
|
+
assert_equal(d1[i].account, d2[i].account)
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
def test_eager_with_multiple_associations_with_same_table_belongs_to
|
389
|
+
firm_types = [:firm, :firm_with_basic_id, :firm_with_other_name, :firm_with_condition]
|
390
|
+
d1 = find_all_ordered(Client)
|
391
|
+
d2 = find_all_ordered(Client, firm_types)
|
392
|
+
d1.each_index do |i|
|
393
|
+
assert_equal(d1[i], d2[i])
|
394
|
+
firm_types.each { |type| assert_equal(d1[i].send(type), d2[i].send(type)) }
|
395
|
+
end
|
396
|
+
end
|
397
|
+
def test_eager_with_valid_association_as_string_not_symbol
|
398
|
+
assert_nothing_raised { Post.find(:all, :include => 'comments') }
|
399
|
+
end
|
400
|
+
|
401
|
+
def test_preconfigured_includes_with_belongs_to
|
402
|
+
author = posts(:welcome).author_with_posts
|
403
|
+
assert_equal 5, author.posts.size
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_preconfigured_includes_with_has_one
|
407
|
+
comment = posts(:sti_comments).very_special_comment_with_post
|
408
|
+
assert_equal posts(:sti_comments), comment.post
|
409
|
+
end
|
410
|
+
|
411
|
+
def test_preconfigured_includes_with_has_many
|
412
|
+
posts = authors(:david).posts_with_comments
|
413
|
+
one = posts.detect { |p| p.id == 1 }
|
414
|
+
assert_equal 5, posts.size
|
415
|
+
assert_equal 2, one.comments.size
|
416
|
+
end
|
417
|
+
|
418
|
+
def test_preconfigured_includes_with_habtm
|
419
|
+
posts = authors(:david).posts_with_categories
|
420
|
+
one = posts.detect { |p| p.id == 1 }
|
421
|
+
assert_equal 5, posts.size
|
422
|
+
assert_equal 2, one.categories.size
|
423
|
+
end
|
424
|
+
|
425
|
+
def test_preconfigured_includes_with_has_many_and_habtm
|
426
|
+
posts = authors(:david).posts_with_comments_and_categories
|
427
|
+
one = posts.detect { |p| p.id == 1 }
|
428
|
+
assert_equal 5, posts.size
|
429
|
+
assert_equal 2, one.comments.size
|
430
|
+
assert_equal 2, one.categories.size
|
431
|
+
end
|
432
|
+
|
433
|
+
def test_count_with_include
|
434
|
+
if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
|
435
|
+
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
|
436
|
+
elsif current_adapter?(:OpenBaseAdapter)
|
437
|
+
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(FETCHBLOB(comments.body)) > 15")
|
438
|
+
else
|
439
|
+
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15")
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/post'
|
3
|
+
require 'fixtures/comment'
|
4
|
+
require 'fixtures/project'
|
5
|
+
require 'fixtures/developer'
|
6
|
+
|
7
|
+
class AssociationsExtensionsTest < Test::Unit::TestCase
|
8
|
+
fixtures :projects, :developers, :developers_projects, :comments, :posts
|
9
|
+
|
10
|
+
def test_extension_on_has_many
|
11
|
+
assert_equal comments(:more_greetings), posts(:welcome).comments.find_most_recent
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_extension_on_habtm
|
15
|
+
assert_equal projects(:action_controller), developers(:david).projects.find_most_recent
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_named_extension_on_habtm
|
19
|
+
assert_equal projects(:action_controller), developers(:david).projects_extended_by_name.find_most_recent
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_named_two_extensions_on_habtm
|
23
|
+
assert_equal projects(:action_controller), developers(:david).projects_extended_by_name_twice.find_most_recent
|
24
|
+
assert_equal projects(:active_record), developers(:david).projects_extended_by_name_twice.find_least_recent
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_named_extension_and_block_on_habtm
|
28
|
+
assert_equal projects(:action_controller), developers(:david).projects_extended_by_name_and_block.find_most_recent
|
29
|
+
assert_equal projects(:active_record), developers(:david).projects_extended_by_name_and_block.find_least_recent
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_marshalling_extensions
|
33
|
+
david = developers(:david)
|
34
|
+
assert_equal projects(:action_controller), david.projects.find_most_recent
|
35
|
+
|
36
|
+
david = Marshal.load(Marshal.dump(david))
|
37
|
+
assert_equal projects(:action_controller), david.projects.find_most_recent
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_marshalling_named_extensions
|
41
|
+
david = developers(:david)
|
42
|
+
assert_equal projects(:action_controller), david.projects_extended_by_name.find_most_recent
|
43
|
+
|
44
|
+
david = Marshal.load(Marshal.dump(david))
|
45
|
+
assert_equal projects(:action_controller), david.projects_extended_by_name.find_most_recent
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/post'
|
3
|
+
require 'fixtures/comment'
|
4
|
+
require 'fixtures/author'
|
5
|
+
require 'fixtures/category'
|
6
|
+
require 'fixtures/categorization'
|
7
|
+
|
8
|
+
class InnerJoinAssociationTest < Test::Unit::TestCase
|
9
|
+
fixtures :authors, :posts, :comments, :categories, :categories_posts, :categorizations
|
10
|
+
|
11
|
+
def test_construct_finder_sql_creates_inner_joins
|
12
|
+
sql = Author.send(:construct_finder_sql, :joins => :posts)
|
13
|
+
assert_match /INNER JOIN `?posts`? ON `?posts`?.author_id = authors.id/, sql
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_construct_finder_sql_cascades_inner_joins
|
17
|
+
sql = Author.send(:construct_finder_sql, :joins => {:posts => :comments})
|
18
|
+
assert_match /INNER JOIN `?posts`? ON `?posts`?.author_id = authors.id/, sql
|
19
|
+
assert_match /INNER JOIN `?comments`? ON `?comments`?.post_id = posts.id/, sql
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_construct_finder_sql_inner_joins_through_associations
|
23
|
+
sql = Author.send(:construct_finder_sql, :joins => :categorized_posts)
|
24
|
+
assert_match /INNER JOIN `?categorizations`?.*INNER JOIN `?posts`?/, sql
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_construct_finder_sql_applies_association_conditions
|
28
|
+
sql = Author.send(:construct_finder_sql, :joins => :categories_like_general, :conditions => "TERMINATING_MARKER")
|
29
|
+
assert_match /INNER JOIN `?categories`? ON.*AND.*`?General`?.*TERMINATING_MARKER/, sql
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_construct_finder_sql_unpacks_nested_joins
|
33
|
+
sql = Author.send(:construct_finder_sql, :joins => {:posts => [[:comments]]})
|
34
|
+
assert_no_match /inner join.*inner join.*inner join/i, sql, "only two join clauses should be present"
|
35
|
+
assert_match /INNER JOIN `?posts`? ON `?posts`?.author_id = authors.id/, sql
|
36
|
+
assert_match /INNER JOIN `?comments`? ON `?comments`?.post_id = `?posts`?.id/, sql
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_construct_finder_sql_ignores_empty_joins_hash
|
40
|
+
sql = Author.send(:construct_finder_sql, :joins => {})
|
41
|
+
assert_no_match /JOIN/i, sql
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_construct_finder_sql_ignores_empty_joins_array
|
45
|
+
sql = Author.send(:construct_finder_sql, :joins => [])
|
46
|
+
assert_no_match /JOIN/i, sql
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_find_with_implicit_inner_joins_honors_readonly_without_select
|
50
|
+
authors = Author.find(:all, :joins => :posts)
|
51
|
+
assert !authors.empty?, "expected authors to be non-empty"
|
52
|
+
assert authors.all? {|a| a.readonly? }, "expected all authors to be readonly"
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_find_with_implicit_inner_joins_honors_readonly_with_select
|
56
|
+
authors = Author.find(:all, :select => 'authors.*', :joins => :posts)
|
57
|
+
assert !authors.empty?, "expected authors to be non-empty"
|
58
|
+
assert authors.all? {|a| !a.readonly? }, "expected no authors to be readonly"
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_find_with_implicit_inner_joins_honors_readonly_false
|
62
|
+
authors = Author.find(:all, :joins => :posts, :readonly => false)
|
63
|
+
assert !authors.empty?, "expected authors to be non-empty"
|
64
|
+
assert authors.all? {|a| !a.readonly? }, "expected no authors to be readonly"
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_find_with_implicit_inner_joins_does_not_set_associations
|
68
|
+
authors = Author.find(:all, :select => 'authors.*', :joins => :posts)
|
69
|
+
assert !authors.empty?, "expected authors to be non-empty"
|
70
|
+
assert authors.all? {|a| !a.send(:instance_variables).include?("@posts")}, "expected no authors to have the @posts association loaded"
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_count_honors_implicit_inner_joins
|
74
|
+
real_count = Author.find(:all).sum{|a| a.posts.count }
|
75
|
+
assert_equal real_count, Author.count(:joins => :posts), "plain inner join count should match the number of referenced posts records"
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_calculate_honors_implicit_inner_joins
|
79
|
+
real_count = Author.find(:all).sum{|a| a.posts.count }
|
80
|
+
assert_equal real_count, Author.calculate(:count, 'authors.id', :joins => :posts), "plain inner join count should match the number of referenced posts records"
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_calculate_honors_implicit_inner_joins_and_distinct_and_conditions
|
84
|
+
real_count = Author.find(:all).select {|a| a.posts.any? {|p| p.title =~ /^Welcome/} }.length
|
85
|
+
authors_with_welcoming_post_titles = Author.calculate(:count, 'authors.id', :joins => :posts, :distinct => true, :conditions => "posts.title like 'Welcome%'")
|
86
|
+
assert_equal real_count, authors_with_welcoming_post_titles, "inner join and conditions should have only returned authors posting titles starting with 'Welcome'"
|
87
|
+
end
|
88
|
+
end
|