1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Enhancement: refactor and add tests to the query methods argument errors

This commit is contained in:
Martin Jaime 2021-05-22 19:41:23 -03:00
parent e888e3cf87
commit 0cb3bd17e3
3 changed files with 66 additions and 28 deletions

View file

@ -173,7 +173,7 @@ module ActiveRecord
#
# User.includes(:posts).where(posts: { name: 'example' })
def includes(*args)
check_if_method_has_arguments!(:includes, args)
check_if_method_has_arguments!(__callee__, args)
spawn.includes!(*args)
end
@ -189,7 +189,7 @@ module ActiveRecord
# # FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" =
# # "users"."id"
def eager_load(*args)
check_if_method_has_arguments!(:eager_load, args)
check_if_method_has_arguments!(__callee__, args)
spawn.eager_load!(*args)
end
@ -203,7 +203,7 @@ module ActiveRecord
# User.preload(:posts)
# # SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3)
def preload(*args)
check_if_method_has_arguments!(:preload, args)
check_if_method_has_arguments!(__callee__, args)
spawn.preload!(*args)
end
@ -236,7 +236,7 @@ module ActiveRecord
# User.includes(:posts).where("posts.name = 'foo'").references(:posts)
# # Query now knows the string references posts, so adds a JOIN
def references(*table_names)
check_if_method_has_arguments!(:references, table_names)
check_if_method_has_arguments!(__callee__, table_names)
spawn.references!(*table_names)
end
@ -294,7 +294,7 @@ module ActiveRecord
return super()
end
check_if_method_has_arguments!(:select, fields, "Call `select' with at least one field.")
check_if_method_has_arguments!(__callee__, fields, "Call `select' with at least one field.")
spawn._select!(*fields)
end
@ -314,7 +314,7 @@ module ActiveRecord
# This is short-hand for <tt>unscope(:select).select(fields)</tt>.
# Note that we're unscoping the entire select statement.
def reselect(*args)
check_if_method_has_arguments!(:reselect, args)
check_if_method_has_arguments!(__callee__, args)
spawn.reselect!(*args)
end
@ -345,7 +345,7 @@ module ActiveRecord
# User.select([:id, :first_name]).group(:id, :first_name).first(3)
# # => [#<User id: 1, first_name: "Bill">, #<User id: 2, first_name: "Earl">, #<User id: 3, first_name: "Beto">]
def group(*args)
check_if_method_has_arguments!(:group, args)
check_if_method_has_arguments!(__callee__, args)
spawn.group!(*args)
end
@ -374,7 +374,7 @@ module ActiveRecord
# User.order('name DESC, email')
# # SELECT "users".* FROM "users" ORDER BY name DESC, email
def order(*args)
check_if_method_has_arguments!(:order, args) do
check_if_method_has_arguments!(__callee__, args) do
sanitize_order_arguments(args)
end
spawn.order!(*args)
@ -397,7 +397,7 @@ module ActiveRecord
#
# generates a query with 'ORDER BY id ASC, name ASC'.
def reorder(*args)
check_if_method_has_arguments!(:reorder, args) do
check_if_method_has_arguments!(__callee__, args) do
sanitize_order_arguments(args) unless args.all?(&:blank?)
end
spawn.reorder!(*args)
@ -450,7 +450,7 @@ module ActiveRecord
# has_many :comments, -> { unscope(where: :trashed) }
#
def unscope(*args)
check_if_method_has_arguments!(:unscope, args)
check_if_method_has_arguments!(__callee__, args)
spawn.unscope!(*args)
end
@ -512,7 +512,7 @@ module ActiveRecord
# User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id")
# # SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id
def joins(*args)
check_if_method_has_arguments!(:joins, args)
check_if_method_has_arguments!(__callee__, args)
spawn.joins!(*args)
end
@ -1074,7 +1074,7 @@ module ActiveRecord
# Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)")
# # SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
def optimizer_hints(*args)
check_if_method_has_arguments!(:optimizer_hints, args)
check_if_method_has_arguments!(__callee__, args)
spawn.optimizer_hints!(*args)
end
@ -1116,7 +1116,7 @@ module ActiveRecord
#
# The SQL block comment delimiters, "/*" and "*/", will be added automatically.
def annotate(*args)
check_if_method_has_arguments!(:annotate, args)
check_if_method_has_arguments!(__callee__, args)
spawn.annotate!(*args)
end
@ -1596,11 +1596,11 @@ module ActiveRecord
# Post.references() # raises an error
# Post.references([]) # does not raise an error
#
# This particular method should be called with a method_name and the args
# This particular method should be called with a method_name (__callee__) and the args
# passed into that method as an input. For example:
#
# def references(*args)
# check_if_method_has_arguments!("references", args)
# check_if_method_has_arguments!(__callee__, args)
# ...
# end
def check_if_method_has_arguments!(method_name, args, message = nil)

View file

@ -88,5 +88,18 @@ module ActiveRecord
ensure
Post.enumerate_columns_in_select_statements = original_value
end
def test_select_without_any_arguments
error = assert_raises(ArgumentError) { Post.select }
assert_equal "Call `select' with at least one field.", error.message
end
def test_select_with_block_without_any_arguments
error = assert_raises(ArgumentError) do
Post.select("invalid_argument") { }
end
assert_equal "`select' with block doesn't take arguments.", error.message
end
end
end

View file

@ -538,19 +538,44 @@ class RelationTest < ActiveRecord::TestCase
end
def test_no_arguments_to_query_methods_raise_errors
assert_raises(ArgumentError) { Topic.references() }
assert_raises(ArgumentError) { Topic.includes() }
assert_raises(ArgumentError) { Topic.preload() }
assert_raises(ArgumentError) { Topic.group() }
assert_raises(ArgumentError) { Topic.reorder() }
assert_raises(ArgumentError) { Topic.order() }
assert_raises(ArgumentError) { Topic.eager_load() }
assert_raises(ArgumentError) { Topic.reselect() }
assert_raises(ArgumentError) { Topic.unscope() }
assert_raises(ArgumentError) { Topic.joins() }
assert_raises(ArgumentError) { Topic.left_joins() }
assert_raises(ArgumentError) { Topic.optimizer_hints() }
assert_raises(ArgumentError) { Topic.annotate() }
error = assert_raises(ArgumentError) { Topic.references() }
assert_equal "The method .references() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.includes() }
assert_equal "The method .includes() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.preload() }
assert_equal "The method .preload() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.group() }
assert_equal "The method .group() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.reorder() }
assert_equal "The method .reorder() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.order() }
assert_equal "The method .order() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.eager_load() }
assert_equal "The method .eager_load() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.reselect() }
assert_equal "The method .reselect() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.unscope() }
assert_equal "The method .unscope() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.joins() }
assert_equal "The method .joins() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.left_joins() }
assert_equal "The method .left_joins() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.optimizer_hints() }
assert_equal "The method .optimizer_hints() must contain arguments.", error.message
error = assert_raises(ArgumentError) { Topic.annotate() }
assert_equal "The method .annotate() must contain arguments.", error.message
end
def test_blank_like_arguments_to_query_methods_dont_raise_errors