aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Neves <arthurnn@gmail.com>2014-04-03 10:39:05 -0400
committerArthur Neves <arthurnn@gmail.com>2014-04-03 16:40:01 -0400
commit815c9deae8de557688e1c99aabe30454bcbe5970 (patch)
treedf11e8eb468b6b22540d7127a698966257848bf2
parentae110ce5d4de8cb3a22f826b0e824f333d2b2742 (diff)
downloadrails-815c9deae8de557688e1c99aabe30454bcbe5970.tar.gz
rails-815c9deae8de557688e1c99aabe30454bcbe5970.tar.bz2
rails-815c9deae8de557688e1c99aabe30454bcbe5970.zip
Block a few default Class methods as scope name.
Add tests to make sure scopes cannot be create with names such as: private, protected, public. Make sure enum values don't collide with those methods too.
-rw-r--r--activerecord/CHANGELOG.md8
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb4
-rw-r--r--activerecord/test/cases/enum_test.rb1
-rw-r--r--activerecord/test/cases/scoping/named_scoping_test.rb3
4 files changed, 15 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 4abfdfa81b..98fe0fbd62 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,11 @@
+* Block a few default Class methods as scope name.
+
+ For instance, this will raise:
+
+ scope :public, -> { where(status: 1) }
+
+ *arthurnn*
+
* Fixed error when using `with_options` with lambda.
Fixes #9805.
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index ea48a13ea8..4b1733619a 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -29,6 +29,8 @@ module ActiveRecord
end
}
+ BLACKLISTED_CLASS_METHODS = %w(private public protected)
+
class AttributeMethodCache
def initialize
@module = Module.new
@@ -132,7 +134,7 @@ module ActiveRecord
# A class method is 'dangerous' if it is already (re)defined by Active Record, but
# not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
def dangerous_class_method?(method_name)
- class_method_defined_within?(method_name, Base)
+ BLACKLISTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
end
def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc
diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb
index f8ebd7caee..47de3dec98 100644
--- a/activerecord/test/cases/enum_test.rb
+++ b/activerecord/test/cases/enum_test.rb
@@ -194,6 +194,7 @@ class EnumTest < ActiveRecord::TestCase
:valid, # generates #valid?, which conflicts with an AR method
:save, # generates #save!, which conflicts with an AR method
:proposed, # same value as an existing enum
+ :public, :private, :protected, # generates a method that conflict with ruby words
]
conflicts.each_with_index do |value, i|
diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb
index f0ad9ebb8a..59ec2dd6a4 100644
--- a/activerecord/test/cases/scoping/named_scoping_test.rb
+++ b/activerecord/test/cases/scoping/named_scoping_test.rb
@@ -291,6 +291,9 @@ class NamedScopingTest < ActiveRecord::TestCase
:relation, # private class method on AR::Base
:new, # redefined class method on AR::Base
:all, # a default scope
+ :public,
+ :protected,
+ :private
]
non_conflicts = [