From 30104b0fc0357aa634f9b340f5d5be11b3538355 Mon Sep 17 00:00:00 2001 From: Andrew Haines Date: Wed, 7 Nov 2012 21:35:02 +0000 Subject: [PATCH] Move :infer option to CollectionDecorator --- lib/draper/collection_decorator.rb | 13 +++++++++++-- lib/draper/decoratable.rb | 2 +- lib/draper/decorator.rb | 8 ++------ spec/draper/decorator_spec.rb | 24 +++++++----------------- 4 files changed, 21 insertions(+), 26 deletions(-) diff --git a/lib/draper/collection_decorator.rb b/lib/draper/collection_decorator.rb index 2c256cf..7cbb714 100644 --- a/lib/draper/collection_decorator.rb +++ b/lib/draper/collection_decorator.rb @@ -11,7 +11,8 @@ module Draper # @param source collection to decorate # @param options [Hash] passed to each item's decorator (except # for the keys listed below) - # @option options [Class] :with the class used to decorate items + # @option options [Class,Symbol] :with the class used to decorate + # items, or `:infer` to call each item's `decorate` method instead def initialize(source, options = {}) @source = source @decorator_class = options.delete(:with) || self.class.inferred_decorator_class @@ -23,7 +24,7 @@ module Draper end def decorated_collection - @decorated_collection ||= source.collect {|item| decorator_class.decorate(item, options) } + @decorated_collection ||= source.collect {|item| decorate_item(item) } end def find(*args, &block) @@ -61,6 +62,14 @@ module Draper protected + def decorate_item(item) + if decorator_class == :infer + item.decorate(options) + else + decorator_class.decorate(item, options) + end + end + def self.inferred_decorator_class decorator_name = "#{name.chomp("Decorator").singularize}Decorator" decorator_uninferrable if decorator_name == name diff --git a/lib/draper/decoratable.rb b/lib/draper/decoratable.rb index 4e0a8b5..410e314 100644 --- a/lib/draper/decoratable.rb +++ b/lib/draper/decoratable.rb @@ -2,7 +2,7 @@ module Draper::Decoratable extend ActiveSupport::Concern def decorator(options = {}) - @decorator ||= decorator_class.decorate(self, options.merge(:infer => false)) + @decorator ||= decorator_class.decorate(self) block_given? ? yield(@decorator) : @decorator end alias_method :decorate, :decorator diff --git a/lib/draper/decorator.rb b/lib/draper/decorator.rb index c55b51c..f2e2927 100755 --- a/lib/draper/decorator.rb +++ b/lib/draper/decorator.rb @@ -124,17 +124,13 @@ module Draper # individually decorated objects. # # @param [Object] input instance(s) to wrap - # @param [Hash] options (optional) - # @option options [Boolean] :infer If true, each model will be - # wrapped by its inferred decorator. + # @param [Hash] options options to be passed to the decorator def self.decorate(input, options = {}) if input.instance_of?(self) input.options = options unless options.empty? return input elsif input.respond_to?(:each) && !input.is_a?(Struct) && (!defined?(Sequel) || !input.is_a?(Sequel::Model)) - Draper::CollectionDecorator.new(input, options.merge(with: self)) - elsif options[:infer] - input.decorator(options) + Draper::CollectionDecorator.new(input, options.reverse_merge(with: self)) else new(input, options) end diff --git a/spec/draper/decorator_spec.rb b/spec/draper/decorator_spec.rb index d7222b9..4078bb3 100755 --- a/spec/draper/decorator_spec.rb +++ b/spec/draper/decorator_spec.rb @@ -30,7 +30,7 @@ describe Draper::Decorator do end end - context ".decorate" do + describe ".decorate" do context "without any context" do subject { Draper::Decorator.decorate(source) } @@ -127,8 +127,8 @@ describe Draper::Decorator do let(:source) { [Product.new, Widget.new] } it "returns a collection of wrapped objects all with the same decorator" do - subject.first.class.should be Draper::Decorator - subject.last.class.should be Draper::Decorator + subject.first.should be_an_instance_of Draper::Decorator + subject.last.should be_an_instance_of Draper::Decorator end end @@ -138,28 +138,18 @@ describe Draper::Decorator do let(:source) { Product.new } it "returns a decorator of the type explicity used in the call" do - subject.class.should be Draper::Decorator + subject.should be_an_instance_of Draper::Decorator end end context "returns a collection containing only the explicit decorator used in the call" do - subject { Draper::Decorator.decorate(source, infer: true).to_ary } + subject { Draper::Decorator.decorate(source, with: :infer) } let(:source) { [Product.new, Widget.new] } it "returns a mixed collection of wrapped objects" do - subject.first.class.should be ProductDecorator - subject.last.class.should be WidgetDecorator - end - end - - context "when given a single object" do - subject { Draper::Decorator.decorate(source, infer: true) } - - let(:source) { Product.new } - - it "can also infer its decorator" do - subject.class.should be ProductDecorator + subject.first.should be_an_instance_of ProductDecorator + subject.last.should be_an_instance_of WidgetDecorator end end end