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:
commit
6521360f22
3 changed files with 24 additions and 14 deletions
|
@ -6,6 +6,11 @@ module Draper
|
|||
|
||||
DEFAULT_DENIED = Object.new.methods << :method_missing
|
||||
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
|
||||
|
||||
# Initialize a new decorator instance by passing in
|
||||
|
@ -20,7 +25,6 @@ module Draper
|
|||
self.class.model_class = input.class if model_class.nil?
|
||||
@model = input
|
||||
self.context = context
|
||||
build_methods
|
||||
end
|
||||
|
||||
# Proxies to the class specified by `decorates` to automatically
|
||||
|
@ -133,20 +137,26 @@ module Draper
|
|||
@model == other.model
|
||||
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
|
||||
def select_methods
|
||||
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
|
||||
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
|
||||
|
|
|
@ -163,11 +163,11 @@ describe Draper::Base do
|
|||
let(:subject_with_allows){ DecoratorWithAllows.new(source) }
|
||||
|
||||
it "should echo the allowed method" do
|
||||
subject_with_allows.should respond_to(:upcase)
|
||||
subject_with_allows.should respond_to(:goodnight_moon)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
class DecoratorWithAllows < Draper::Base
|
||||
allows :upcase
|
||||
allows :goodnight_moon
|
||||
end
|
Loading…
Reference in a new issue