diff --git a/lib/draper.rb b/lib/draper.rb index ecff734..79ac9d7 100644 --- a/lib/draper.rb +++ b/lib/draper.rb @@ -18,3 +18,11 @@ require 'draper/railtie' if defined?(Rails) # Test Support require 'draper/test/rspec_integration' if defined?(RSpec) and RSpec.respond_to?(:configure) require 'draper/test/minitest_integration' if defined?(MiniTest::Rails) + +module Draper + class UninferrableDecoratorError < NameError + def initialize(klass) + super("Could not infer a decorator for #{klass}.") + end + end +end diff --git a/lib/draper/collection_decorator.rb b/lib/draper/collection_decorator.rb index 1e177cd..71926c1 100644 --- a/lib/draper/collection_decorator.rb +++ b/lib/draper/collection_decorator.rb @@ -65,7 +65,7 @@ module Draper singular_name = name.chomp("Decorator").singularize "#{singular_name}Decorator".constantize rescue NameError - raise NameError, "Could not infer a decorator for #{name}. Please specify the decorator class when creating instances of this class." + raise Draper::UninferrableDecoratorError.new(self) end end end diff --git a/lib/draper/decoratable.rb b/lib/draper/decoratable.rb index 4286666..4e0a8b5 100644 --- a/lib/draper/decoratable.rb +++ b/lib/draper/decoratable.rb @@ -25,12 +25,14 @@ module Draper::Decoratable module ClassMethods def decorate(options = {}) - decorator_proxy = decorator_class.decorate(self.scoped, options) - block_given? ? yield(decorator_proxy) : decorator_proxy + collection_decorator = decorator_class.decorate(self.scoped, options) + block_given? ? yield(collection_decorator) : collection_decorator end def decorator_class "#{model_name}Decorator".constantize + rescue NameError + raise Draper::UninferrableDecoratorError.new(self) end end end diff --git a/spec/draper/collection_decorator_spec.rb b/spec/draper/collection_decorator_spec.rb index 81b0dee..fa5a107 100644 --- a/spec/draper/collection_decorator_spec.rb +++ b/spec/draper/collection_decorator_spec.rb @@ -90,7 +90,7 @@ describe Draper::CollectionDecorator do end it "raises when decorates an empty array without the klass" do - expect{EnumerableProxy.decorate([])}.to raise_error + expect{EnumerableProxy.decorate([])}.to raise_error Draper::UninferrableDecoratorError end end diff --git a/spec/draper/decoratable_spec.rb b/spec/draper/decoratable_spec.rb index ab276da..6228a93 100644 --- a/spec/draper/decoratable_spec.rb +++ b/spec/draper/decoratable_spec.rb @@ -25,7 +25,7 @@ describe Draper::Decoratable do describe "#decorated_with?" do it "returns false" do - subject.should_not be_decorated_with(ProductDecorator) + subject.should_not be_decorated_with ProductDecorator end end @@ -35,6 +35,20 @@ describe Draper::Decoratable do end end + describe ".decorator_class" do + context "when the decorator can be inferred from the model" do + it "returns the inferred decorator class" do + Product.decorator_class.should be ProductDecorator + end + end + + context "when the decorator can't be inferred from the model" do + it "throws an UninferrableDecoratorError" do + expect{UninferrableDecoratorModel.decorator_class}.to raise_error Draper::UninferrableDecoratorError + end + end + end + describe Draper::Decoratable::ClassMethods do shared_examples_for "a call to Draper::Decoratable::ClassMethods#decorate" do subject { klass.limit } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5d2a055..c5bd986 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -25,6 +25,7 @@ require './spec/support/samples/sequel_product' require './spec/support/samples/specific_product_decorator' require './spec/support/samples/some_thing' require './spec/support/samples/some_thing_decorator' +require './spec/support/samples/uninferrable_decorator_model' require './spec/support/samples/widget' require './spec/support/samples/widget_decorator' diff --git a/spec/support/samples/uninferrable_decorator_model.rb b/spec/support/samples/uninferrable_decorator_model.rb new file mode 100644 index 0000000..d7b760a --- /dev/null +++ b/spec/support/samples/uninferrable_decorator_model.rb @@ -0,0 +1,3 @@ +class UninferrableDecoratorModel + include Draper::Decoratable +end