1
0
Fork 0
mirror of https://github.com/drapergem/draper synced 2023-03-27 23:21:17 -04:00

Merge pull request #29 from michaelfairley/method_missing

Changing from dynamic method generation to use method missing for performance improvement.
This commit is contained in:
Jeff Casimir 2011-10-03 13:29:22 -07:00
commit 6521360f22
3 changed files with 24 additions and 14 deletions

View file

@ -6,6 +6,11 @@ module Draper
DEFAULT_DENIED = Object.new.methods << :method_missing DEFAULT_DENIED = Object.new.methods << :method_missing
FORCED_PROXY = [:to_param] FORCED_PROXY = [:to_param]
FORCED_PROXY.each do |method|
define_method method do |*args, &block|
model.send method, *args, &block
end
end
self.denied = DEFAULT_DENIED self.denied = DEFAULT_DENIED
# Initialize a new decorator instance by passing in # Initialize a new decorator instance by passing in
@ -20,7 +25,6 @@ module Draper
self.class.model_class = input.class if model_class.nil? self.class.model_class = input.class if model_class.nil?
@model = input @model = input
self.context = context self.context = context
build_methods
end end
# Proxies to the class specified by `decorates` to automatically # Proxies to the class specified by `decorates` to automatically
@ -133,20 +137,26 @@ module Draper
@model == other.model @model == other.model
end end
def respond_to?(method)
if select_methods.include?(method)
model.respond_to?(method)
else
super
end
end
def method_missing(method, *args, &block)
if select_methods.include?(method)
model.send(method, *args, &block)
else
super
end
end
private private
def select_methods def select_methods
specified = self.allowed || (model.public_methods.map{|s| s.to_sym} - denied.map{|s| s.to_sym}) specified = self.allowed || (model.public_methods.map{|s| s.to_sym} - denied.map{|s| s.to_sym})
(specified - self.public_methods.map{|s| s.to_sym}) + FORCED_PROXY (specified - self.public_methods.map{|s| s.to_sym}) + FORCED_PROXY
end end
def build_methods
select_methods.each do |method|
(class << self; self; end).class_eval do
define_method method do |*args, &block|
model.send method, *args, &block
end
end
end
end
end end
end end

View file

@ -163,11 +163,11 @@ describe Draper::Base do
let(:subject_with_allows){ DecoratorWithAllows.new(source) } let(:subject_with_allows){ DecoratorWithAllows.new(source) }
it "should echo the allowed method" do it "should echo the allowed method" do
subject_with_allows.should respond_to(:upcase) subject_with_allows.should respond_to(:goodnight_moon)
end end
it "should echo _only_ the allowed method" do it "should echo _only_ the allowed method" do
subject_with_allows.should_not respond_to(:downcase) subject_with_allows.should_not respond_to(:hello_world)
end end
end end

View file

@ -1,3 +1,3 @@
class DecoratorWithAllows < Draper::Base class DecoratorWithAllows < Draper::Base
allows :upcase allows :goodnight_moon
end end