Rails' delegates are even more useful than I knew

April 9, 2011 Pivotal Labs

File this under “things I wish I’d known about years ago”…

Do you use delegate in Rails? It’s a great way to avoid Law of Demeter violations. Let’s say you’re modeling people, who belong to households:

class Person
  belongs_to :household
  delegate :address, to: household
end

class Household
  # has a string attribute 'address'
end

Now we can get the address of a Person with the Demeter-friendly
person.address, rather than the trainwreck person.household.address.
When we decide suddenly that a person sometimes needs to override its
household’s address, we can change this to:

class Person
  belongs_to :household

  def address
    overriding_address || household.address
  end
end

and we don’t have to change any code which refers to person.address.

But! What about this?

class Person
  # has a string attribute 'name'
end

class Business
  belongs_to :owner, class_name: 'Person'
end

How do we get the name of a business’s owner? We could say
business.owner.name, but that’s a Demeter violation. We could delegate,
but then we’d have business.name, which would be wrong. Luckily, the
authors of delegate have thought of this:

class Business
  belongs_to :owner, class_name: 'Person'
  delegate :name, to: :owner, prefix: true
end

The prefix: true option gives us business.owner_name, which is much
better. You can also specify a custom prefix instead of true.

After doing this manually by defining methods for years, I feel silly to
learn that the prefix option has been around since 2008!

About the Author

Biography

More Content by Pivotal Labs
Previous
Demystifying Autoscale: The Tale of an API Mashup
Demystifying Autoscale: The Tale of an API Mashup

For most applications autoscale is not fire-and-forget, but it shouldn’t require a fancy PaaS, either. Jess...

Next
Politics Junkies… This One's For You!
Politics Junkies… This One's For You!

Can you believe we are headed for our fourth Canadian election in 7 years? With the Harper Conservative kno...

Enter curious. Exit smarter.

Learn More