diff options
Diffstat (limited to 'activerecord/test/cases/relation_test.rb')
-rw-r--r-- | activerecord/test/cases/relation_test.rb | 97 |
1 files changed, 54 insertions, 43 deletions
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index 5fb32270b7..b424ca91de 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "cases/helper" require "models/post" require "models/comment" @@ -6,25 +8,7 @@ require "models/rating" module ActiveRecord class RelationTest < ActiveRecord::TestCase - fixtures :posts, :comments, :authors, :author_addresses - - FakeKlass = Struct.new(:table_name, :name) do - extend ActiveRecord::Delegation::DelegateCache - - inherited self - - def self.connection - Post.connection - end - - def self.table_name - "fake_table" - end - - def self.sanitize_sql_for_order(sql) - sql - end - end + fixtures :posts, :comments, :authors, :author_addresses, :ratings def test_construction relation = Relation.new(FakeKlass, :b, nil) @@ -70,8 +54,8 @@ module ActiveRecord def test_has_values relation = Relation.new(Post, Post.arel_table, Post.predicate_builder) - relation.where! relation.table[:id].eq(10) - assert_equal({ id: 10 }, relation.where_values_hash) + relation.where!(id: 10) + assert_equal({ "id" => 10 }, relation.where_values_hash) end def test_values_wrong_table @@ -84,16 +68,11 @@ module ActiveRecord relation = Relation.new(Post, Post.arel_table, Post.predicate_builder) left = relation.table[:id].eq(10) right = relation.table[:id].eq(10) - combine = left.and right + combine = left.or(right) relation.where! combine assert_equal({}, relation.where_values_hash) end - def test_table_name_delegates_to_klass - relation = Relation.new(FakeKlass.new("posts"), :b, Post.predicate_builder) - assert_equal "posts", relation.table_name - end - def test_scope_for_create relation = Relation.new(FakeKlass, :b, nil) assert_equal({}, relation.scope_for_create) @@ -101,28 +80,27 @@ module ActiveRecord def test_create_with_value relation = Relation.new(Post, Post.arel_table, Post.predicate_builder) - hash = { hello: "world" } - relation.create_with_value = hash - assert_equal hash, relation.scope_for_create + relation.create_with_value = { hello: "world" } + assert_equal({ "hello" => "world" }, relation.scope_for_create) end def test_create_with_value_with_wheres relation = Relation.new(Post, Post.arel_table, Post.predicate_builder) - relation.where! relation.table[:id].eq(10) + assert_equal({}, relation.scope_for_create) + + relation.where!(id: 10) + assert_equal({ "id" => 10 }, relation.scope_for_create) + relation.create_with_value = { hello: "world" } - assert_equal({ hello: "world", id: 10 }, relation.scope_for_create) + assert_equal({ "hello" => "world", "id" => 10 }, relation.scope_for_create) end - # FIXME: is this really wanted or expected behavior? - def test_scope_for_create_is_cached + def test_empty_scope relation = Relation.new(Post, Post.arel_table, Post.predicate_builder) - assert_equal({}, relation.scope_for_create) - - relation.where! relation.table[:id].eq(10) - assert_equal({}, relation.scope_for_create) + assert relation.empty_scope? - relation.create_with_value = { hello: "world" } - assert_equal({}, relation.scope_for_create) + relation.merge!(relation) + assert relation.empty_scope? end def test_bad_constants_raise_errors @@ -210,7 +188,7 @@ module ActiveRecord relation = Relation.new(klass, :b, nil) relation.merge!(where: ["foo = ?", "bar"]) - assert_equal Relation::WhereClause.new(["foo = bar"], []), relation.where_clause + assert_equal Relation::WhereClause.new(["foo = bar"]), relation.where_clause end def test_merging_readonly_false @@ -224,7 +202,26 @@ module ActiveRecord def test_relation_merging_with_merged_joins_as_symbols special_comments_with_ratings = SpecialComment.joins(:ratings) posts_with_special_comments_with_ratings = Post.group("posts.id").joins(:special_comments).merge(special_comments_with_ratings) - assert_equal({ 2 => 1, 4 => 3, 5 => 1 }, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count) + assert_equal({ 4 => 2 }, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count) + end + + def test_relation_merging_with_merged_symbol_joins_keeps_inner_joins + queries = capture_sql { Author.joins(:posts).merge(Post.joins(:comments)).to_a } + + nb_inner_join = queries.sum { |sql| sql.scan(/INNER\s+JOIN/i).size } + assert_equal 2, nb_inner_join, "Wrong amount of INNER JOIN in query" + assert queries.none? { |sql| /LEFT\s+(OUTER)?\s+JOIN/i.match?(sql) }, "Shouldn't have any LEFT JOIN in query" + end + + def test_relation_merging_with_merged_symbol_joins_has_correct_size_and_count + # Has one entry per comment + merged_authors_with_commented_posts_relation = Author.joins(:posts).merge(Post.joins(:comments)) + + post_ids_with_author = Post.joins(:author).pluck(:id) + manual_comments_on_post_that_have_author = Comment.where(post_id: post_ids_with_author).pluck(:id) + + assert_equal manual_comments_on_post_that_have_author.size, merged_authors_with_commented_posts_relation.count + assert_equal manual_comments_on_post_that_have_author.size, merged_authors_with_commented_posts_relation.to_a.size end def test_relation_merging_with_joins_as_join_dependency_pick_proper_parent @@ -277,18 +274,32 @@ module ActiveRecord assert_equal({ 2 => 1, 4 => 3, 5 => 1 }, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count) end + def test_relation_merging_keeps_joining_order + authors = Author.where(id: 1) + posts = Post.joins(:author).merge(authors) + comments = Comment.joins(:post).merge(posts) + ratings = Rating.joins(:comment).merge(comments) + + assert_equal 3, ratings.count + end + class EnsureRoundTripTypeCasting < ActiveRecord::Type::Value def type :string end + def cast(value) + raise value unless value == "value from user" + "cast value" + end + def deserialize(value) raise value unless value == "type cast for database" "type cast from database" end def serialize(value) - raise value unless value == "value from user" + raise value unless value == "cast value" "type cast for database" end end |