class Module

def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)

The target method must be public, otherwise it will raise +NoMethodError+.

Foo.new("Bar").name # raises NoMethodError: undefined method `name'

end
delegate :name, to: :@bar, allow_nil: true

end
@bar = bar
def initialize(bar)
class Foo

does not respond to the method:
:allow_nil option, and thus an exception is still raised if said object
Note that if the target is not +nil+ then the call is attempted regardless of the

User.new.age # nil

end
delegate :age, to: :profile, allow_nil: true
has_one :profile
class User < ActiveRecord::Base

condition:
But if not having a profile yet is fine and should not be an error

# => Module::DelegationError: User#age delegated to profile.age, but profile is nil
User.new.age

end
delegate :age, to: :profile
has_one :profile
class User < ActiveRecord::Base

use the :allow_nil option.
+Module::DelegationError+ is raised. If you wish to instead return +nil+,
If the target is +nil+ and does not respond to the delegated method a

User.new.age # => 2
User.new.date_of_birth # => NoMethodError: private method `date_of_birth' called for #
User.new.first_name # => "Tomas"

end
end
Date.today.year - date_of_birth.year
def age

delegate :date_of_birth, to: :profile, private: true
delegate :first_name, to: :profile
has_one :profile
class User < ActiveRecord::Base

Pass private: true to change that.
The delegated methods are public by default.

invoice.customer_address # => 'Vimmersvej 13'
invoice.customer_name # => 'John Doe'
invoice = Invoice.new(john_doe)

end
delegate :name, :address, to: :client, prefix: :customer
class Invoice < Struct.new(:client)

It is also possible to supply a custom prefix.

invoice.client_address # => "Vimmersvej 13"
invoice.client_name # => "John Doe"
invoice = Invoice.new(john_doe)
john_doe = Person.new('John Doe', 'Vimmersvej 13')

end
delegate :name, :address, to: :client, prefix: true
class Invoice < Struct.new(:client)

Person = Struct.new(:name, :address)

delegated to.
is true, the delegate methods are prefixed with the name of the object being
Delegates can optionally be prefixed using the :prefix option. If the value

Foo.new.hello # => "world"

end
delegate :hello, to: :class

end
"world"
def self.hello
class Foo

It's also possible to delegate a method to the class by using +:class+:

Foo.new.max # => 11
Foo.new.min # => 4
Foo.new.sum # => 6

end
delegate :max, to: :@instance_array
delegate :min, to: :@@class_array
delegate :sum, to: :CONSTANT_ARRAY
end
@instance_array = [8,9,10,11]
def initialize

@@class_array = [4,5,6,7]
CONSTANT_ARRAY = [0,1,2,3]
class Foo

by providing them as a symbols:
Methods can be delegated to instance variables, class variables, or constants

Foo.new.goodbye # => "goodbye"

end
delegate :hello, :goodbye, to: :greeter
belongs_to :greeter
class Foo < ActiveRecord::Base

Multiple delegates to the same target are allowed:

Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #
Foo.new.hello # => "hello"

end
delegate :hello, to: :greeter
belongs_to :greeter
class Foo < ActiveRecord::Base

end
end
'goodbye'
def goodbye

end
'hello'
def hello
class Greeter < ActiveRecord::Base

Delegation is particularly useful with Active Record associations:

(also a symbol or string).
strings) and the name of the target object via the :to option
The macro receives one or more method names (specified as symbols or

* :private - If set to true, changes method visibility to private
from being raised
* :allow_nil - If set to true, prevents a +Module::DelegationError+
* :prefix - Prefixes the new method with the target name or a custom prefix
* :to - Specifies the target object name as a symbol or string
==== Options

public methods as your own.
Provides a +delegate+ class method to easily expose contained objects'
def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)
  unless to
    raise ArgumentError, "Delegation needs a target. Supply a keyword argument 'to' (e.g. delegate :hello, to: :greeter)."
  end
  if prefix == true && /^[^a-z_]/.match?(to)
    raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
  end
  method_prefix = \
    if prefix
      "#{prefix == true ? to : prefix}_"
    else
      ""
    end
  location = caller_locations(1, 1).first
  file, line = location.path, location.lineno
  to = to.to_s
  to = "self.#{to}" if DELEGATION_RESERVED_METHOD_NAMES.include?(to)
  method_def = []
  method_names = []
  methods.map do |method|
    method_name = prefix ? "#{method_prefix}#{method}" : method
    method_names << method_name.to_sym
    # Attribute writer methods only accept one argument. Makes sure []=
    # methods still accept two arguments.
    definition = /[^\]]=\z/.match?(method) ? "arg" : "..."
    # The following generated method calls the target exactly once, storing
    # the returned value in a dummy variable.
    #
    # Reason is twofold: On one hand doing less calls is in general better.
    # On the other hand it could be that the target has side-effects,
    # whereas conceptually, from the user point of view, the delegator should
    # be doing one call.
    if allow_nil
      method = method.to_s
      method_def <<
        "def #{method_name}(#{definition})" <<
        "  _ = #{to}" <<
        "  if !_.nil? || nil.respond_to?(:#{method})" <<
        "    _.#{method}(#{definition})" <<
        "  end" <<
        "end"
    else
      method = method.to_s
      method_name = method_name.to_s
      method_def <<
        "def #{method_name}(#{definition})" <<
        "  _ = #{to}" <<
        "  _.#{method}(#{definition})" <<
        "rescue NoMethodError => e" <<
        "  if _.nil? && e.name == :#{method}" <<
        %(   raise DelegationError, "#{self}##{method_name} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") <<
        "  else" <<
        "    raise" <<
        "  end" <<
        "end"
    end
  end
  module_eval(method_def.join(";"), file, line)
  private(*method_names) if private
  method_names
end