mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
6c235dd958
The column is primarily used for type casting, which we're trying to separate from the idea of a column. Since what we really need is the combination of a name, type, and value, let's use the object that we already have to represent that concept, rather than this tuple. No consumers of the bind values have been changed, only the producers (outside of tests which care too much about internals). This is *finally* possible since the bind values are now produced from a reasonable number of lcoations.
150 lines
5.1 KiB
Ruby
150 lines
5.1 KiB
Ruby
require 'cases/helper'
|
|
require 'models/author'
|
|
require 'models/comment'
|
|
require 'models/developer'
|
|
require 'models/computer'
|
|
require 'models/post'
|
|
require 'models/project'
|
|
require 'models/rating'
|
|
|
|
class RelationMergingTest < ActiveRecord::TestCase
|
|
fixtures :developers, :comments, :authors, :posts
|
|
|
|
def test_relation_merging
|
|
devs = Developer.where("salary >= 80000").merge(Developer.limit(2)).merge(Developer.order('id ASC').where("id < 3"))
|
|
assert_equal [developers(:david), developers(:jamis)], devs.to_a
|
|
|
|
dev_with_count = Developer.limit(1).merge(Developer.order('id DESC')).merge(Developer.select('developers.*'))
|
|
assert_equal [developers(:poor_jamis)], dev_with_count.to_a
|
|
end
|
|
|
|
def test_relation_to_sql
|
|
post = Post.first
|
|
sql = post.comments.to_sql
|
|
assert_match(/.?post_id.? = #{post.id}\Z/i, sql)
|
|
end
|
|
|
|
def test_relation_merging_with_arel_equalities_keeps_last_equality
|
|
devs = Developer.where(Developer.arel_table[:salary].eq(80000)).merge(
|
|
Developer.where(Developer.arel_table[:salary].eq(9000))
|
|
)
|
|
assert_equal [developers(:poor_jamis)], devs.to_a
|
|
end
|
|
|
|
def test_relation_merging_with_arel_equalities_keeps_last_equality_with_non_attribute_left_hand
|
|
salary_attr = Developer.arel_table[:salary]
|
|
devs = Developer.where(
|
|
Arel::Nodes::NamedFunction.new('abs', [salary_attr]).eq(80000)
|
|
).merge(
|
|
Developer.where(
|
|
Arel::Nodes::NamedFunction.new('abs', [salary_attr]).eq(9000)
|
|
)
|
|
)
|
|
assert_equal [developers(:poor_jamis)], devs.to_a
|
|
end
|
|
|
|
def test_relation_merging_with_eager_load
|
|
relations = []
|
|
relations << Post.order('comments.id DESC').merge(Post.eager_load(:last_comment)).merge(Post.all)
|
|
relations << Post.eager_load(:last_comment).merge(Post.order('comments.id DESC')).merge(Post.all)
|
|
|
|
relations.each do |posts|
|
|
post = posts.find { |p| p.id == 1 }
|
|
assert_equal Post.find(1).last_comment, post.last_comment
|
|
end
|
|
end
|
|
|
|
def test_relation_merging_with_locks
|
|
devs = Developer.lock.where("salary >= 80000").order("id DESC").merge(Developer.limit(2))
|
|
assert devs.locked.present?
|
|
end
|
|
|
|
def test_relation_merging_with_preload
|
|
[Post.all.merge(Post.preload(:author)), Post.preload(:author).merge(Post.all)].each do |posts|
|
|
assert_queries(2) { assert posts.first.author }
|
|
end
|
|
end
|
|
|
|
def test_relation_merging_with_joins
|
|
comments = Comment.joins(:post).where(:body => 'Thank you for the welcome').merge(Post.where(:body => 'Such a lovely day'))
|
|
assert_equal 1, comments.count
|
|
end
|
|
|
|
def test_relation_merging_with_association
|
|
assert_queries(2) do # one for loading post, and another one merged query
|
|
post = Post.where(:body => 'Such a lovely day').first
|
|
comments = Comment.where(:body => 'Thank you for the welcome').merge(post.comments)
|
|
assert_equal 1, comments.count
|
|
end
|
|
end
|
|
|
|
test "merge collapses wheres from the LHS only" do
|
|
left = Post.where(title: "omg").where(comments_count: 1)
|
|
right = Post.where(title: "wtf").where(title: "bbq")
|
|
|
|
expected = [left.bind_values[1]] + right.bind_values
|
|
merged = left.merge(right)
|
|
|
|
assert_equal expected, merged.bind_values
|
|
assert !merged.to_sql.include?("omg")
|
|
assert merged.to_sql.include?("wtf")
|
|
assert merged.to_sql.include?("bbq")
|
|
end
|
|
|
|
def test_merging_reorders_bind_params
|
|
post = Post.first
|
|
right = Post.where(id: 1)
|
|
left = Post.where(title: post.title)
|
|
|
|
merged = left.merge(right)
|
|
assert_equal post, merged.first
|
|
end
|
|
|
|
def test_merging_compares_symbols_and_strings_as_equal
|
|
post = PostThatLoadsCommentsInAnAfterSaveHook.create!(title: "First Post", body: "Blah blah blah.")
|
|
assert_equal "First comment!", post.comments.where(body: "First comment!").first_or_create.body
|
|
end
|
|
end
|
|
|
|
class MergingDifferentRelationsTest < ActiveRecord::TestCase
|
|
fixtures :posts, :authors, :developers
|
|
|
|
test "merging where relations" do
|
|
hello_by_bob = Post.where(body: "hello").joins(:author).
|
|
merge(Author.where(name: "Bob")).order("posts.id").pluck("posts.id")
|
|
|
|
assert_equal [posts(:misc_by_bob).id,
|
|
posts(:other_by_bob).id], hello_by_bob
|
|
end
|
|
|
|
test "merging order relations" do
|
|
posts_by_author_name = Post.limit(3).joins(:author).
|
|
merge(Author.order(:name)).pluck("authors.name")
|
|
|
|
assert_equal ["Bob", "Bob", "David"], posts_by_author_name
|
|
|
|
posts_by_author_name = Post.limit(3).joins(:author).
|
|
merge(Author.order("name")).pluck("authors.name")
|
|
|
|
assert_equal ["Bob", "Bob", "David"], posts_by_author_name
|
|
end
|
|
|
|
test "merging order relations (using a hash argument)" do
|
|
posts_by_author_name = Post.limit(4).joins(:author).
|
|
merge(Author.order(name: :desc)).pluck("authors.name")
|
|
|
|
assert_equal ["Mary", "Mary", "Mary", "David"], posts_by_author_name
|
|
end
|
|
|
|
test "relation merging (using a proc argument)" do
|
|
dev = Developer.where(name: "Jamis").first
|
|
|
|
comment_1 = dev.comments.create!(body: "I'm Jamis", post: Post.first)
|
|
rating_1 = comment_1.ratings.create!
|
|
|
|
comment_2 = dev.comments.create!(body: "I'm John", post: Post.first)
|
|
comment_2.ratings.create!
|
|
|
|
assert_equal dev.ratings, [rating_1]
|
|
end
|
|
end
|