2013-01-14 03:27:58 +00:00
|
|
|
module Draper
|
|
|
|
module AutomaticDelegation
|
|
|
|
extend ActiveSupport::Concern
|
|
|
|
|
2017-04-03 16:24:01 +00:00
|
|
|
# Delegates missing instance methods to the source object. Note: This will delegate `super`
|
|
|
|
# method calls to `object` as well. Calling `super` will first try to call the method on
|
|
|
|
# the parent decorator class. If no method exists on the parent class, it will then try
|
|
|
|
# to call the method on the `object`.
|
2021-01-27 16:44:29 +00:00
|
|
|
ruby2_keywords def method_missing(method, *args, &block)
|
2013-01-14 03:27:58 +00:00
|
|
|
return super unless delegatable?(method)
|
|
|
|
|
2017-04-03 16:24:01 +00:00
|
|
|
object.send(method, *args, &block)
|
2013-01-14 03:27:58 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Checks if the decorator responds to an instance method, or is able to
|
|
|
|
# proxy it to the source object.
|
2013-02-11 23:08:21 +00:00
|
|
|
def respond_to_missing?(method, include_private = false)
|
2013-01-14 03:27:58 +00:00
|
|
|
super || delegatable?(method)
|
|
|
|
end
|
|
|
|
|
|
|
|
# @private
|
|
|
|
def delegatable?(method)
|
2020-02-11 16:47:49 +00:00
|
|
|
return if private_methods(false).include?(method)
|
2019-03-18 16:35:29 +00:00
|
|
|
|
2013-04-30 13:10:52 +00:00
|
|
|
object.respond_to?(method)
|
2013-01-14 03:27:58 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
module ClassMethods
|
|
|
|
# Proxies missing class methods to the source class.
|
2021-01-27 16:44:29 +00:00
|
|
|
ruby2_keywords def method_missing(method, *args, &block)
|
2013-01-14 03:27:58 +00:00
|
|
|
return super unless delegatable?(method)
|
|
|
|
|
2013-04-30 18:37:05 +00:00
|
|
|
object_class.send(method, *args, &block)
|
2013-01-14 03:27:58 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Checks if the decorator responds to a class method, or is able to proxy
|
|
|
|
# it to the source class.
|
2013-02-11 23:08:21 +00:00
|
|
|
def respond_to_missing?(method, include_private = false)
|
2013-01-14 03:27:58 +00:00
|
|
|
super || delegatable?(method)
|
|
|
|
end
|
|
|
|
|
|
|
|
# @private
|
|
|
|
def delegatable?(method)
|
2013-04-30 18:37:05 +00:00
|
|
|
object_class? && object_class.respond_to?(method)
|
2013-01-14 03:27:58 +00:00
|
|
|
end
|
2013-02-17 10:38:47 +00:00
|
|
|
|
|
|
|
# @private
|
|
|
|
# Avoids reloading the model class when ActiveSupport clears autoloaded
|
|
|
|
# dependencies in development mode.
|
|
|
|
def before_remove_const
|
|
|
|
end
|
2013-01-14 03:27:58 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
included do
|
|
|
|
private :delegatable?
|
|
|
|
private_class_method :delegatable?
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|