From 4f3bf6ebb7e873d2d7f29ec67a5f0ff4935535ac Mon Sep 17 00:00:00 2001 From: Jeff Casimir Date: Sat, 8 Oct 2011 22:47:08 -0400 Subject: [PATCH] Proxy class methods using method_missing --- lib/draper/base.rb | 18 +++++++++--------- spec/base_spec.rb | 22 +++++++++++++++------- spec/samples/decorator.rb | 5 +++++ spec/samples/product.rb | 4 ++++ 4 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 spec/samples/decorator.rb diff --git a/lib/draper/base.rb b/lib/draper/base.rb index 69b70f9..0a40e51 100644 --- a/lib/draper/base.rb +++ b/lib/draper/base.rb @@ -115,14 +115,6 @@ module Draper self.send(:include, Draper::LazyHelpers) end - # Use primarily by `form_for`, this returns an instance of - # `ActiveModel::Name` set to the wrapped model's class name - # - # @return [ActiveModel::Name] model_name - def self.model_name - ActiveModel::Name.new(model_class) - end - # Fetch the original wrapped model. # # @return [Object] original_model @@ -137,7 +129,7 @@ module Draper @model == other.model end - def respond_to?(method) + def respond_to?(method, include_private = false) if select_methods.include?(method) model.respond_to?(method) else @@ -152,6 +144,14 @@ module Draper super end end + + def self.method_missing(method, *args, &block) + model_class.send(method, *args, &block) + end + + def self.respond_to?(method, include_private = false) + super || model_class.respond_to?(method) + end private def select_methods diff --git a/spec/base_spec.rb b/spec/base_spec.rb index 16ca67e..23b7fe8 100644 --- a/spec/base_spec.rb +++ b/spec/base_spec.rb @@ -3,9 +3,23 @@ require 'draper' describe Draper::Base do before(:each){ ApplicationController.new.set_current_view_context } - subject{ Draper::Base.new(source) } + subject{ Decorator.new(source) } let(:source){ Product.new } + context("proxying class methods") do + it "should pass missing class method calls on to the wrapped class" do + subject.class.sample_class_method.should == "sample class method" + end + + it "should respond_to a wrapped class method" do + subject.class.should respond_to(:sample_class_method) + end + + it "should still respond_to it's own class methods" do + subject.class.should respond_to(:own_class_method) + end + end + context(".helpers") do it "should have a valid view_context" do subject.helpers.should be @@ -19,12 +33,6 @@ describe Draper::Base do end end - context(".model_name") do - it "should return an ActiveModel::Name instance" do - Draper::Base.model_name.should be_instance_of(ActiveModel::Name) - end - end - context(".decorates") do it "sets the model class for the decorator" do ProductDecorator.new(source).model_class.should == Product diff --git a/spec/samples/decorator.rb b/spec/samples/decorator.rb new file mode 100644 index 0000000..9569853 --- /dev/null +++ b/spec/samples/decorator.rb @@ -0,0 +1,5 @@ +class Decorator < Draper::Base + def self.own_class_method + "own class method" + end +end \ No newline at end of file diff --git a/spec/samples/product.rb b/spec/samples/product.rb index fea85c1..4cea434 100644 --- a/spec/samples/product.rb +++ b/spec/samples/product.rb @@ -3,6 +3,10 @@ class Product < ActiveRecord::Base return Product.new end + def self.sample_class_method + "sample class method" + end + def hello_world "Hello, World" end