Proxy class methods using method_missing

This commit is contained in:
Jeff Casimir 2011-10-08 22:47:08 -04:00
parent 6abf506c82
commit 4f3bf6ebb7
4 changed files with 33 additions and 16 deletions

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
class Decorator < Draper::Base
def self.own_class_method
"own class method"
end
end

View File

@ -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