diff options
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/base.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/model.rb | 49 | ||||
-rw-r--r-- | activerecord/test/cases/inclusion_test.rb | 26 |
3 files changed, 55 insertions, 22 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 6df68bade0..a4705b24ca 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -325,4 +325,4 @@ module ActiveRecord #:nodoc: end end -ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Model::DeprecationProxy) +ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Model::DeprecationProxy.new) diff --git a/activerecord/lib/active_record/model.rb b/activerecord/lib/active_record/model.rb index 3d0a39e979..a326dabcd3 100644 --- a/activerecord/lib/active_record/model.rb +++ b/activerecord/lib/active_record/model.rb @@ -109,26 +109,39 @@ module ActiveRecord end end - module DeprecationProxy #:nodoc: - class << self - instance_methods.each { |m| undef_method m unless m =~ /^__|^object_id$|^instance_eval$/ } - - def method_missing(name, *args, &block) - if Model.respond_to?(name) - Model.send(name, *args, &block) - else - ActiveSupport::Deprecation.warn( - "The object passed to the active_record load hook was previously ActiveRecord::Base " \ - "(a Class). Now it is ActiveRecord::Model (a Module). You have called `#{name}' which " \ - "is only defined on ActiveRecord::Base. Please change your code so that it works with " \ - "a module rather than a class. (Model is included in Base, so anything added to Model " \ - "will be available on Base as well.)" - ) - Base.send(name, *args, &block) - end + class DeprecationProxy < BasicObject #:nodoc: + def initialize(model = Model, base = Base) + @model = model + @base = base + end + + def method_missing(name, *args, &block) + if @model.respond_to?(name, true) + @model.send(name, *args, &block) + else + ::ActiveSupport::Deprecation.warn( + "The object passed to the active_record load hook was previously ActiveRecord::Base " \ + "(a Class). Now it is ActiveRecord::Model (a Module). You have called `#{name}' which " \ + "is only defined on ActiveRecord::Base. Please change your code so that it works with " \ + "a module rather than a class. (Model is included in Base, so anything added to Model " \ + "will be available on Base as well.)" + ) + @base.send(name, *args, &block) end + end - alias send method_missing + alias send method_missing + + def extend(*mods) + ::ActiveSupport::Deprecation.warn( + "The object passed to the active_record load hook was previously ActiveRecord::Base " \ + "(a Class). Now it is ActiveRecord::Model (a Module). You have called `extend' which " \ + "would add singleton methods to Model. This is presumably not what you want, since the " \ + "methods would not be inherited down to Base. Rather than using extend, please use " \ + "ActiveSupport::Concern + include, which will ensure that your class methods are " \ + "inherited." + ) + @base.extend *mods end end end diff --git a/activerecord/test/cases/inclusion_test.rb b/activerecord/test/cases/inclusion_test.rb index 9b9c09d2d8..8f095e4953 100644 --- a/activerecord/test/cases/inclusion_test.rb +++ b/activerecord/test/cases/inclusion_test.rb @@ -84,8 +84,10 @@ class InclusionUnitTest < ActiveRecord::TestCase end def test_deprecation_proxy - assert_equal ActiveRecord::Model.name, ActiveRecord::Model::DeprecationProxy.name - assert_equal ActiveRecord::Base.superclass, assert_deprecated { ActiveRecord::Model::DeprecationProxy.superclass } + proxy = ActiveRecord::Model::DeprecationProxy.new + + assert_equal ActiveRecord::Model.name, proxy.name + assert_equal ActiveRecord::Base.superclass, assert_deprecated { proxy.superclass } sup, sup2 = nil, nil ActiveSupport.on_load(:__test_active_record_model_deprecation) do @@ -93,11 +95,29 @@ class InclusionUnitTest < ActiveRecord::TestCase sup2 = send(:superclass) end assert_deprecated do - ActiveSupport.run_load_hooks(:__test_active_record_model_deprecation, ActiveRecord::Model::DeprecationProxy) + ActiveSupport.run_load_hooks(:__test_active_record_model_deprecation, proxy) end assert_equal ActiveRecord::Base.superclass, sup assert_equal ActiveRecord::Base.superclass, sup2 end + + test "including in deprecation proxy" do + model, base = ActiveRecord::Model.dup, ActiveRecord::Base.dup + proxy = ActiveRecord::Model::DeprecationProxy.new(model, base) + + mod = Module.new + proxy.include mod + assert model < mod + end + + test "extending in deprecation proxy" do + model, base = ActiveRecord::Model.dup, ActiveRecord::Base.dup + proxy = ActiveRecord::Model::DeprecationProxy.new(model, base) + + mod = Module.new + assert_deprecated { proxy.extend mod } + assert base.singleton_class < mod + end end class InclusionFixturesTest < ActiveRecord::TestCase |