From eea4c866a61c1d7fbbfe757602eebc09296e05a0 Mon Sep 17 00:00:00 2001 From: Chris Heald Date: Thu, 10 May 2012 17:50:22 -0700 Subject: [PATCH 1/2] If special ActiveModel methods like #id, #errors, and #to_param are defined directly on the decorator, do not redefine them as proxy methods. --- lib/draper/active_model_support.rb | 6 ++++-- lib/draper/base.rb | 0 spec/draper/base_spec.rb | 20 ++++++++++++++++--- spec/spec_helper.rb | 1 + spec/support/samples/decorator_with_allows.rb | 0 5 files changed, 22 insertions(+), 5 deletions(-) mode change 100644 => 100755 lib/draper/active_model_support.rb mode change 100644 => 100755 lib/draper/base.rb mode change 100644 => 100755 spec/draper/base_spec.rb mode change 100644 => 100755 spec/spec_helper.rb mode change 100644 => 100755 spec/support/samples/decorator_with_allows.rb diff --git a/lib/draper/active_model_support.rb b/lib/draper/active_model_support.rb old mode 100644 new mode 100755 index 2e4ab35..f8e5104 --- a/lib/draper/active_model_support.rb +++ b/lib/draper/active_model_support.rb @@ -13,8 +13,10 @@ module Draper::ActiveModelSupport class << base self end.class_eval do - send(:define_method, method_name) do |*args, &block| - model.send(method_name, *args, &block) + if !base.class.instance_methods.include?(method_name) || base.class.instance_method(method_name).owner === Draper::Base + send(:define_method, method_name) do |*args, &block| + model.send(method_name, *args, &block) + end end end end diff --git a/lib/draper/base.rb b/lib/draper/base.rb old mode 100644 new mode 100755 diff --git a/spec/draper/base_spec.rb b/spec/draper/base_spec.rb old mode 100644 new mode 100755 index cec1b6f..4872794 --- a/spec/draper/base_spec.rb +++ b/spec/draper/base_spec.rb @@ -215,19 +215,33 @@ describe Draper::Base do end context "when an ActiveModel descendant" do - it "should always proxy to_param" do + it "should always proxy to_param if it is not defined on the decorator itself" do source.stub(:to_param).and_return(1) Draper::Base.new(source).to_param.should == 1 end - it "should always proxy id" do + it "should always proxy id if it is not defined on the decorator itself" do source.stub(:id).and_return(123456789) Draper::Base.new(source).id.should == 123456789 end - it "should always proxy errors" do + it "should always proxy errors if it is not defined on the decorator itself" do Draper::Base.new(source).errors.should be_an_instance_of ActiveModel::Errors end + + it "should never proxy to_param if it is defined on the decorator itself" do + source.stub(:to_param).and_return(1) + DecoratorWithSpecialMethods.new(source).to_param.should == "foo" + end + + it "should never proxy id if it is defined on the decorator itself" do + source.stub(:id).and_return(123456789) + DecoratorWithSpecialMethods.new(source).id.should == 1337 + end + + it "should never proxy errors if it is defined on the decorator itself" do + DecoratorWithSpecialMethods.new(source).errors.should be_an_instance_of Array + end end context "when not an ActiveModel descendant" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb old mode 100644 new mode 100755 index f761574..28746d1 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,6 +14,7 @@ require './spec/support/samples/decorator_with_allows' require './spec/support/samples/decorator_with_multiple_allows' require './spec/support/samples/decorator_with_application_helper' require './spec/support/samples/decorator_with_denies' +require './spec/support/samples/decorator_with_special_methods' require './spec/support/samples/namespaced_product' require './spec/support/samples/namespaced_product_decorator' require './spec/support/samples/non_active_model_product' diff --git a/spec/support/samples/decorator_with_allows.rb b/spec/support/samples/decorator_with_allows.rb old mode 100644 new mode 100755 From 719ddbf808837101161d6b210c74de7d137f4608 Mon Sep 17 00:00:00 2001 From: Chris Heald Date: Thu, 10 May 2012 17:54:31 -0700 Subject: [PATCH 2/2] Add missing file --- .../samples/decorator_with_special_methods.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100755 spec/support/samples/decorator_with_special_methods.rb diff --git a/spec/support/samples/decorator_with_special_methods.rb b/spec/support/samples/decorator_with_special_methods.rb new file mode 100755 index 0000000..90cfeb1 --- /dev/null +++ b/spec/support/samples/decorator_with_special_methods.rb @@ -0,0 +1,13 @@ +class DecoratorWithSpecialMethods < Draper::Base + def to_param + "foo" + end + + def id + 1337 + end + + def errors + ["omg errors!"] + end +end