From 0bbcd19c64710c54e57dcea49e2fb22b1779872e Mon Sep 17 00:00:00 2001 From: Andrew Haines Date: Tue, 30 Oct 2012 22:37:09 +0000 Subject: [PATCH] Drop the Utils module --- lib/draper.rb | 1 - lib/draper/decorator.rb | 31 +++++++++++++++++++++++++------ lib/draper/utils.rb | 17 ----------------- spec/draper/decorator_spec.rb | 16 ++++++++++++++++ spec/utils_spec.rb | 14 -------------- 5 files changed, 41 insertions(+), 38 deletions(-) delete mode 100644 lib/draper/utils.rb delete mode 100644 spec/utils_spec.rb diff --git a/lib/draper.rb b/lib/draper.rb index 54fe6acc..74fd1962 100644 --- a/lib/draper.rb +++ b/lib/draper.rb @@ -1,7 +1,6 @@ require 'action_view' require 'draper/version' -require 'draper/utils' require 'draper/system' require 'draper/active_model_support' require 'draper/view_helpers' diff --git a/lib/draper/decorator.rb b/lib/draper/decorator.rb index 3371e3a4..d0695c4a 100755 --- a/lib/draper/decorator.rb +++ b/lib/draper/decorator.rb @@ -25,13 +25,9 @@ class Decorator def initialize(input, options = {}) input.to_a if input.respond_to?(:to_a) # forces evaluation of a lazy query from AR self.class.model_class = input.class if model_class.nil? - @model = input - if input.instance_of?(self.class) - @model = input.model - elsif Utils.decorators_of(input).include?(self.class) - warn "Reapplying #{self.class} decorator to target that is already decorated with it. Call stack:\n#{caller(1).join "\n"}" - end + self.model = input self.options = options + handle_multiple_decoration if input.is_a?(Draper::Decorator) end # Proxies to the class specified by `decorates` to automatically @@ -176,6 +172,21 @@ def self.last(options = {}) decorate(model_class.last, options) end + # Get the chain of decorators applied to the object. + # + # @return [Array] list of decorator classes + def applied_decorators + chain = model.respond_to?(:applied_decorators) ? model.applied_decorators : [] + chain << self.class + end + + # Checks if a given decorator has been applied. + # + # @param [Class] decorator_class + def decorated_with?(decorator_class) + applied_decorators.include?(decorator_class) + end + # Delegates == to the decorated models # # @return [Boolean] true if other's model == self's model @@ -252,6 +263,14 @@ def allow?(method) self.class.security.allow?(method) end + def handle_multiple_decoration + if model.instance_of?(self.class) + self.model = model.model + elsif model.decorated_with?(self.class) + warn "Reapplying #{self.class} decorator to target that is already decorated with it. Call stack:\n#{caller(1).join("\n")}" + end + end + def find_association_reflection(association) if model.class.respond_to?(:reflect_on_association) model.class.reflect_on_association(association) diff --git a/lib/draper/utils.rb b/lib/draper/utils.rb deleted file mode 100644 index 39bdc71c..00000000 --- a/lib/draper/utils.rb +++ /dev/null @@ -1,17 +0,0 @@ -module Draper - # @api private - module Utils - extend self - - # Returns an array of all decorator classes applied to an instance. - def decorators_of(decorated_instance) - decorators = [] - instance = decorated_instance - while instance.kind_of?(Draper::Decorator) - decorators << instance.class - instance = instance.model - end - decorators - end - end -end diff --git a/spec/draper/decorator_spec.rb b/spec/draper/decorator_spec.rb index 68bf2601..edac2a61 100755 --- a/spec/draper/decorator_spec.rb +++ b/spec/draper/decorator_spec.rb @@ -268,6 +268,22 @@ class CustomDecorator < Draper::Decorator end end + describe "#applied_decorators" do + it "returns a list of decorators applied to a model" do + decorator = ProductDecorator.new(SpecificProductDecorator.new(Product.new)) + decorator.applied_decorators.should == [SpecificProductDecorator, ProductDecorator] + end + end + + describe "#decorated_with?" do + it "checks if a decorator has been applied to a model" do + decorator = ProductDecorator.new(SpecificProductDecorator.new(Product.new)) + decorator.should be_decorated_with ProductDecorator + decorator.should be_decorated_with SpecificProductDecorator + decorator.should_not be_decorated_with WidgetDecorator + end + end + context(".wrapped_object") do it "return the wrapped object" do subject.wrapped_object.should == source diff --git a/spec/utils_spec.rb b/spec/utils_spec.rb deleted file mode 100644 index 19af63fe..00000000 --- a/spec/utils_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'spec_helper' - -describe Draper::Utils do - describe ".decorators_of" do - it "returns a list of decorators applied to a model" do - instance = ProductDecorator.new(SpecificProductDecorator.new(Product.new)) - Draper::Utils.decorators_of(instance).should == [ProductDecorator, SpecificProductDecorator] - end - - it "returns an empty array when instance is not decorated" do - Draper::Utils.decorators_of(Product.new).should be_empty - end - end -end