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

Stop trying to be clever about when to define attribute methods.

There is no meaningful performance penalty in defining attribute
methods, since it only happens once.

There is also no reason *not* to define them, since they get thrown in
an included module, so they will not 'overwrite' anything. In fact, this
is desirable, since it allows us to call super.
This commit is contained in:
Jon Leighton 2011-09-13 23:52:38 +01:00
parent 778c82bea6
commit 3b8a7cf2a7
2 changed files with 1 additions and 34 deletions

View file

@ -38,21 +38,12 @@ module ActiveRecord
end
end
# Checks whether the method is defined in the model or any of its subclasses
# that also derive from Active Record. Raises DangerousAttributeError if the
# method is defined by Active Record though.
def instance_method_already_implemented?(method_name)
if dangerous_attribute_method?(method_name)
raise DangerousAttributeError, "#{method_name} is defined by ActiveRecord"
end
method_name = method_name.to_s
index = ancestors.index(ActiveRecord::Base) || ancestors.length
@_defined_class_methods ||= ancestors.first(index).map { |m|
m.instance_methods(false) | m.private_instance_methods(false)
}.flatten.map {|m| m.to_s }.to_set
@_defined_class_methods.include?(method_name) || generated_attribute_methods.method_defined?(method_name)
super
end
# A method name is 'dangerous' if it is already defined by Active Record, but

View file

@ -431,30 +431,6 @@ class AttributeMethodsTest < ActiveRecord::TestCase
assert topic.is_test?
end
def test_kernel_methods_not_implemented_in_activerecord
%w(test name display y).each do |method|
assert !ActiveRecord::Base.instance_method_already_implemented?(method), "##{method} is defined"
end
end
def test_defined_kernel_methods_implemented_in_model
%w(test name display y).each do |method|
klass = Class.new ActiveRecord::Base
klass.class_eval "def #{method}() 'defined #{method}' end"
assert klass.instance_method_already_implemented?(method), "##{method} is not defined"
end
end
def test_defined_kernel_methods_implemented_in_model_abstract_subclass
%w(test name display y).each do |method|
abstract = Class.new ActiveRecord::Base
abstract.class_eval "def #{method}() 'defined #{method}' end"
abstract.abstract_class = true
klass = Class.new abstract
assert klass.instance_method_already_implemented?(method), "##{method} is not defined"
end
end
def test_raises_dangerous_attribute_error_when_defining_activerecord_method_in_model
%w(save create_or_update).each do |method|
klass = Class.new ActiveRecord::Base