aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/attribute_methods_test.rb
diff options
context:
space:
mode:
authorGodfrey Chan <godfreykfc@gmail.com>2014-02-13 11:49:19 -0800
committerGodfrey Chan <godfreykfc@gmail.com>2014-02-23 11:00:55 -0800
commit41554319f8454f667b5e315339d3e286dbf6e1a4 (patch)
tree6b429827488b2ca7f34095d5f74f208ea6a8301f /activerecord/test/cases/attribute_methods_test.rb
parent96759cf6c6a17053abb6a2b7cd87cdbd5a8420ba (diff)
downloadrails-41554319f8454f667b5e315339d3e286dbf6e1a4.tar.gz
rails-41554319f8454f667b5e315339d3e286dbf6e1a4.tar.bz2
rails-41554319f8454f667b5e315339d3e286dbf6e1a4.zip
Fixed STI classes not defining an attribute method if there is a
conflicting private method defined on its ancestors. The problem is that `method_defined_within?(name, klass, superklass)` only works correclty when `klass` and `superklass` are both `Class`es. If both `klass` and `superklass` are both `Class`es, they share the same inheritance chain, so if a method is defined on `klass` but not `superklass`, this method must be introduced at some point between `klass` and `superklass`. This does not work when `superklass` is a `Module`. A `Module`'s inheritance chain contains just itself. So if a method is defined on `klass` but not on `superklass`, the method could still be defined somewhere upstream, e.g. in `Object`. This fix works by avoiding calling `method_defined_within?` with a module while still fufilling the requirement (checking that the method is defined withing `superclass` but not is not a generated attribute method). 4d8ee288 is likely an attempted partial fix for this problem. This unrolls that fix and properly check the `superclass` as intended. Fixes #11569.
Diffstat (limited to 'activerecord/test/cases/attribute_methods_test.rb')
-rw-r--r--activerecord/test/cases/attribute_methods_test.rb30
1 files changed, 19 insertions, 11 deletions
diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb
index 6c581a432f..aec1ea3972 100644
--- a/activerecord/test/cases/attribute_methods_test.rb
+++ b/activerecord/test/cases/attribute_methods_test.rb
@@ -728,19 +728,27 @@ class AttributeMethodsTest < ActiveRecord::TestCase
assert "unknown attribute: hello", error.message
end
- def test_read_attribute_overwrites_private_method_not_considered_implemented
- # simulate a model with a db column that shares its name an inherited
- # private method (e.g. Object#system)
- #
- Object.class_eval do
- private
- def title; "private!"; end
+ def test_global_methods_are_overwritten
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = 'computers'
+ end
+
+ assert !klass.instance_method_already_implemented?(:system)
+ computer = klass.new
+ assert_nil computer.system
+ end
+
+ def test_global_methods_are_overwritte_when_subclassing
+ klass = Class.new(ActiveRecord::Base) { self.abstract_class = true }
+
+ subklass = Class.new(klass) do
+ self.table_name = 'computers'
end
- assert !@target.instance_method_already_implemented?(:title)
- topic = @target.new
- assert_nil topic.title
- Object.send(:undef_method, :title) # remove test method from object
+ assert !klass.instance_method_already_implemented?(:system)
+ assert !subklass.instance_method_already_implemented?(:system)
+ computer = subklass.new
+ assert_nil computer.system
end
def test_instance_method_should_be_defined_on_the_base_class