Browse files

Bugfix: do not confuse Kernel#Array

On 1.9.2 (and maybe earlier) Kernel#Array will choke on a decorator,
because it just invokes `to_ary` and `to_a` without using `respond_to?`
first, like it does in 1.9.3-p125.

As a work-around, make sure to not create a delegation method in
`method_missing` when the model will not respond to it anyway. The
decorator object will then behave like `Kernel#Array` expects it to.

See #115.
  • Loading branch information...
1 parent 279ea02 commit f6c2acf3f4985b1ea3f882a5111f9d06474e3a95 @avdgaag avdgaag committed Mar 12, 2012
Showing with 10 additions and 4 deletions.
  1. +6 −4 lib/draper/base.rb
  2. +4 −0 spec/draper/base_spec.rb
@@ -204,11 +204,13 @@ def respond_to?(method, include_private = false)
def method_missing(method, *args, &block)
super unless allow?(method)
- self.class.send :define_method, method do |*args, &block|
- model.send method, *args, &block
- end
+ if model.respond_to?(method)
+ self.class.send :define_method, method do |*args, &block|
+ model.send method, *args, &block
+ end
- send method, *args, &block
+ send method, *args, &block
+ end
rescue NoMethodError => no_method_error
super if == method
@@ -622,6 +622,10 @@ class DecoratorWithDeniesAndAllows < Draper::Base
context "when the delegated method calls a non-existant method" do
+ it 'should not try to delegate to non-existant methods to not confuse Kernel#Array' do
+ Array(subject).should be_kind_of(Array)
+ end
it "raises the correct NoMethodError" do

0 comments on commit f6c2acf

Please sign in to comment.