charge.statement.customer.nameThe above code could be used to display the customer's name in the partial. Unfortunately, it assumes
statement will have a customer and customer will have a name. This is easily fixed by changing charge to only talk to it's friends.charge.customer_nameThe simple fix to support this is to define
customer_name in charge, and customer_name in statementclass ChargeThis change is simple enough; however, as the list of methods that require delegation grows your class can become littered with delegation code.
def customer_name
statement.customer_name
end
end
class Statement
def customer_name
customer.name
end
end
Luckily, Forwardable is included in the standard library. Forwardable allows you delegate method calls to an object, on a method by method basis. Using Forwardable the above code becomes:
class ChargeForwardable becomes even more valuable when you need to delegate several methods
extend Forwardable
def_delegators :statement, :customer_name
end
class Statement
extend Forwardable
def_delegator :customer, :name, :customer_name
end
def_delegators :amount_info, :units, :fractions, :currencyFor more info on Law of Demeter and it's advantages check out the definition on Wikipedia. For more info on Forwardable check out the documentation on Ruby-Doc.