mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #31179 from kinnrot/scoping-reserved-names
Scoping reserved names
This commit is contained in:
commit
8633567169
5 changed files with 49 additions and 0 deletions
|
@ -1,3 +1,10 @@
|
|||
* Don't allow scopes to be defined which conflict with instance methods on `Relation`.
|
||||
|
||||
Fixes #31120.
|
||||
|
||||
*kinnrot*
|
||||
|
||||
|
||||
## Rails 5.2.0.beta2 (November 28, 2017) ##
|
||||
|
||||
* No changes.
|
||||
|
|
|
@ -221,6 +221,8 @@ module ActiveRecord
|
|||
def detect_enum_conflict!(enum_name, method_name, klass_method = false)
|
||||
if klass_method && dangerous_class_method?(method_name)
|
||||
raise_conflict_error(enum_name, method_name, type: "class")
|
||||
elsif klass_method && method_defined_within?(method_name, Relation)
|
||||
raise_conflict_error(enum_name, method_name, type: "class", source: Relation.name)
|
||||
elsif !klass_method && dangerous_attribute_method?(method_name)
|
||||
raise_conflict_error(enum_name, method_name)
|
||||
elsif !klass_method && method_defined_within?(method_name, _enum_methods_module, Module)
|
||||
|
|
|
@ -171,6 +171,12 @@ module ActiveRecord
|
|||
"a class method with the same name."
|
||||
end
|
||||
|
||||
if method_defined_within?(name, Relation)
|
||||
raise ArgumentError, "You tried to define a scope named \"#{name}\" " \
|
||||
"on the model \"#{self.name}\", but ActiveRecord::Relation already defined " \
|
||||
"an instance method with the same name."
|
||||
end
|
||||
|
||||
valid_scope_name?(name)
|
||||
extension = Module.new(&block) if block
|
||||
|
||||
|
|
|
@ -308,6 +308,24 @@ class EnumTest < ActiveRecord::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
test "reserved enum values for relation" do
|
||||
relation_method_samples = [
|
||||
:records,
|
||||
:to_ary,
|
||||
:scope_for_create
|
||||
]
|
||||
|
||||
relation_method_samples.each do |value|
|
||||
e = assert_raises(ArgumentError, "enum value `#{value}` should not be allowed") do
|
||||
Class.new(ActiveRecord::Base) do
|
||||
self.table_name = "books"
|
||||
enum category: [:other, value]
|
||||
end
|
||||
end
|
||||
assert_match(/You tried to define an enum named .* on the model/, e.message)
|
||||
end
|
||||
end
|
||||
|
||||
test "overriding enum method should not raise" do
|
||||
assert_nothing_raised do
|
||||
Class.new(ActiveRecord::Base) do
|
||||
|
|
|
@ -151,6 +151,22 @@ class NamedScopingTest < ActiveRecord::TestCase
|
|||
assert_equal "The scope body needs to be callable.", e.message
|
||||
end
|
||||
|
||||
def test_scopes_name_is_relation_method
|
||||
conflicts = [
|
||||
:records,
|
||||
:to_ary,
|
||||
:to_sql,
|
||||
:explain
|
||||
]
|
||||
|
||||
conflicts.each do |name|
|
||||
e = assert_raises ArgumentError do
|
||||
Class.new(Post).class_eval { scope name, -> { where(approved: true) } }
|
||||
end
|
||||
assert_match(/You tried to define a scope named \"#{name}\" on the model/, e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def test_active_records_have_scope_named__all__
|
||||
assert !Topic.all.empty?
|
||||
|
||||
|
|
Loading…
Reference in a new issue