diff --git a/lib/draper/base.rb b/lib/draper/base.rb index 18ff940..0395e83 100644 --- a/lib/draper/base.rb +++ b/lib/draper/base.rb @@ -93,7 +93,13 @@ module Draper # @param [Object] instance(s) to wrap # @param [Hash] options (optional) def self.decorate(input, options = {}) - input.respond_to?(:each) ? Draper::DecoratedEnumerableProxy.new(input, self, options) : new(input, options) + if input.respond_to?(:each) + Draper::DecoratedEnumerableProxy.new(input, self, options) + elsif options[:infer] + input.decorator(options) + else + new(input, options) + end end # Fetch all instances of the decorated class and decorate them. diff --git a/lib/draper/decorated_enumerable_proxy.rb b/lib/draper/decorated_enumerable_proxy.rb index cdf6a83..6738101 100644 --- a/lib/draper/decorated_enumerable_proxy.rb +++ b/lib/draper/decorated_enumerable_proxy.rb @@ -7,11 +7,11 @@ module Draper end def each(&block) - @wrapped_collection.each { |member| block.call(@klass.new(member, @options)) } + @wrapped_collection.each { |member| block.call(@klass.decorate(member, @options)) } end def to_ary - @wrapped_collection.map { |member| @klass.new(member, @options) } + @wrapped_collection.map { |member| @klass.decorate(member, @options) } end def method_missing (method, *args, &block) diff --git a/lib/draper/model_support.rb b/lib/draper/model_support.rb index b4546a6..64ce42e 100644 --- a/lib/draper/model_support.rb +++ b/lib/draper/model_support.rb @@ -1,9 +1,9 @@ module Draper::ModelSupport def decorator(options = {}) - @decorator ||= "#{self.class.name}Decorator".constantize.decorate(self, options) + @decorator ||= "#{self.class.name}Decorator".constantize.decorate(self, options.merge(:infer => false)) block_given? ? yield(@decorator) : @decorator end - + alias :decorate :decorator module ClassMethods diff --git a/spec/draper/base_spec.rb b/spec/draper/base_spec.rb index ebe5e15..8a15136 100644 --- a/spec/draper/base_spec.rb +++ b/spec/draper/base_spec.rb @@ -181,6 +181,47 @@ describe Draper::Base do end end + context "does not infer collections by default" do + subject { Draper::Base.decorate(source).to_ary } + + let(:source) { [Product.new, Widget.new] } + + it "returns a collection of wrapped objects all with the same decorator" do + subject.first.class.name.should eql 'Draper::Base' + subject.last.class.name.should eql 'Draper::Base' + end + end + + context "does not infer single items by default" do + subject { Draper::Base.decorate(source) } + + let(:source) { Product.new } + + it "returns a decorator of the type explicity used in the call" do + subject.class.should eql Draper::Base + end + end + + context "returns a collection containing only the explicit decorator used in the call" do + subject { Draper::Base.decorate(source, :infer => true).to_ary } + + let(:source) { [Product.new, Widget.new] } + + it "returns a mixed collection of wrapped objects" do + subject.first.class.should eql ProductDecorator + subject.last.class.should eql WidgetDecorator + end + end + + context "when given a single object" do + subject { Draper::Base.decorate(source, :infer => true) } + + let(:source) { Product.new } + + it "can also infer its decorator" do + subject.class.should eql ProductDecorator + end + end end context('.==') do diff --git a/spec/samples/widget.rb b/spec/samples/widget.rb new file mode 100644 index 0000000..10ec6c3 --- /dev/null +++ b/spec/samples/widget.rb @@ -0,0 +1,2 @@ +class Widget < Product +end diff --git a/spec/samples/widget_decorator.rb b/spec/samples/widget_decorator.rb new file mode 100644 index 0000000..15fa69d --- /dev/null +++ b/spec/samples/widget_decorator.rb @@ -0,0 +1,2 @@ +class WidgetDecorator < ProductDecorator +end diff --git a/spec/support/samples/widget.rb b/spec/support/samples/widget.rb new file mode 100644 index 0000000..10ec6c3 --- /dev/null +++ b/spec/support/samples/widget.rb @@ -0,0 +1,2 @@ +class Widget < Product +end diff --git a/spec/support/samples/widget_decorator.rb b/spec/support/samples/widget_decorator.rb new file mode 100644 index 0000000..15fa69d --- /dev/null +++ b/spec/support/samples/widget_decorator.rb @@ -0,0 +1,2 @@ +class WidgetDecorator < ProductDecorator +end