From f5f27243c3f0c37bff4872e1e78521e570ff1e4f Mon Sep 17 00:00:00 2001 From: Sam-Serpoosh Date: Sun, 19 May 2013 13:01:36 -0500 Subject: [PATCH 1/4] Alias `object` to `#{model_name}` If we have an `ArticleDecorator` there is going to be a method added to it named `article` which is convenient for the user. --- lib/draper/decorator.rb | 9 +++++++++ spec/draper/decorator_spec.rb | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/draper/decorator.rb b/lib/draper/decorator.rb index b2593c7..c2f256b 100755 --- a/lib/draper/decorator.rb +++ b/lib/draper/decorator.rb @@ -16,6 +16,15 @@ module Draper # @return [Hash] extra data to be used in user-defined methods. attr_accessor :context + def self.inherited(klass) + begin + alias_name = klass.name.downcase.gsub(/decorator/, "").to_sym + klass.send(:define_method, alias_name) do + object + end + rescue; end + end + # Wraps an object in a new instance of the decorator. # # Decorators may be applied to other decorators. However, applying a diff --git a/spec/draper/decorator_spec.rb b/spec/draper/decorator_spec.rb index 329c2f4..b5ff6a0 100755 --- a/spec/draper/decorator_spec.rb +++ b/spec/draper/decorator_spec.rb @@ -361,6 +361,23 @@ module Draper end end + describe "aliasing object to wrapped model name" do + class ::ProductDecorator < Decorator; end + class ::Product + attr_reader :name + def initialize + @name = "bob" + end + end + + it "aliases object to wrapped model name" do + decorator = ProductDecorator.new(Product.new) + + expect(decorator.product).not_to be nil + expect(decorator.product.name).to eq "bob" + end + end + describe "#to_model" do it "returns the decorator" do decorator = Decorator.new(Model.new) From 9bd86b982a37496cfdbbd16087b1e969b24ba9c2 Mon Sep 17 00:00:00 2001 From: Andrew Haines Date: Mon, 20 May 2013 11:16:01 +0100 Subject: [PATCH 2/4] Require NameError#missing_name? from ActiveSupport --- lib/draper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/draper.rb b/lib/draper.rb index a821518..f5b1fbc 100644 --- a/lib/draper.rb +++ b/lib/draper.rb @@ -6,6 +6,7 @@ require 'active_model/serializers/xml' require 'active_support/inflector' require 'active_support/core_ext/hash/keys' require 'active_support/core_ext/hash/reverse_merge' +require 'active_support/core_ext/name_error' require 'draper/version' require 'draper/view_helpers' From a239d93288553aabdc63054ef61b429336e32f3c Mon Sep 17 00:00:00 2001 From: Andrew Haines Date: Mon, 20 May 2013 11:16:34 +0100 Subject: [PATCH 3/4] Improve aliasing to object class name --- lib/draper/decorator.rb | 19 ++++++++-------- spec/draper/decorator_spec.rb | 43 +++++++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/lib/draper/decorator.rb b/lib/draper/decorator.rb index c2f256b..bb12b96 100755 --- a/lib/draper/decorator.rb +++ b/lib/draper/decorator.rb @@ -16,15 +16,6 @@ module Draper # @return [Hash] extra data to be used in user-defined methods. attr_accessor :context - def self.inherited(klass) - begin - alias_name = klass.name.downcase.gsub(/decorator/, "").to_sym - klass.send(:define_method, alias_name) do - object - end - rescue; end - end - # Wraps an object in a new instance of the decorator. # # Decorators may be applied to other decorators. However, applying a @@ -66,6 +57,7 @@ module Draper # @return [void] def self.decorates(object_class) @object_class = object_class.to_s.camelize.constantize + alias_object_to_object_class_name end # Returns the source class corresponding to the decorator class, as set by @@ -228,6 +220,15 @@ module Draper private + def self.inherited(subclass) + subclass.alias_object_to_object_class_name + super + end + + def self.alias_object_to_object_class_name + alias_method object_class.name.underscore, :object if object_class? + end + def self.object_class_name raise NameError if name.nil? || name.demodulize !~ /.+Decorator$/ name.chomp("Decorator") diff --git a/spec/draper/decorator_spec.rb b/spec/draper/decorator_spec.rb index b5ff6a0..e317b36 100755 --- a/spec/draper/decorator_spec.rb +++ b/spec/draper/decorator_spec.rb @@ -361,20 +361,43 @@ module Draper end end - describe "aliasing object to wrapped model name" do - class ::ProductDecorator < Decorator; end - class ::Product - attr_reader :name - def initialize - @name = "bob" + describe "aliasing object to object class name" do + context "when object_class is inferrable from the decorator name" do + it "aliases object to the object class name" do + object = stub + decorator = ProductDecorator.new(object) + + expect(decorator.product).to be object end end - it "aliases object to wrapped model name" do - decorator = ProductDecorator.new(Product.new) + context "when object_class is set by decorates" do + it "aliases object to the object class name" do + decorator_class = Class.new(Decorator) { decorates Product } + object = stub + decorator = decorator_class.new(object) - expect(decorator.product).not_to be nil - expect(decorator.product.name).to eq "bob" + expect(decorator.product).to be object + end + end + + context "when object_class's name is several words long" do + it "underscores the method name" do + stub_const "LongWindedModel", Class.new + decorator_class = Class.new(Decorator) { decorates LongWindedModel } + object = stub + decorator = decorator_class.new(object) + + expect(decorator.long_winded_model).to be object + end + end + + context "when object_class is not set" do + it "does not alias object" do + decorator_class = Class.new(Decorator) + + expect(decorator_class.instance_methods).to eq Decorator.instance_methods + end end end From 0a09c096a66408b1f21dad0bd3c22dc4976b2dc7 Mon Sep 17 00:00:00 2001 From: Andrew Haines Date: Mon, 27 May 2013 16:52:07 +0100 Subject: [PATCH 4/4] Only define MongoidPostDecorator when using Mongoid --- spec/dummy/app/decorators/mongoid_post_decorator.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/dummy/app/decorators/mongoid_post_decorator.rb b/spec/dummy/app/decorators/mongoid_post_decorator.rb index 61596e4..42d87e0 100644 --- a/spec/dummy/app/decorators/mongoid_post_decorator.rb +++ b/spec/dummy/app/decorators/mongoid_post_decorator.rb @@ -1,2 +1,4 @@ -class MongoidPostDecorator < Draper::Decorator +if defined?(Mongoid) + class MongoidPostDecorator < Draper::Decorator + end end