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
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
class DecoratorWithAllows < Draper::Base
|
class DecoratorWithAllows < Draper::Base
|
||||||
allows :upcase
|
allows :goodnight_moon
|
||||||
end
|
end
|
Loading…
Reference in a new issue