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
Hello World
Hello World

Welcome to the Cloud Foundry blog. You can read more about the scope of Cloud Foundry, the industry’s firs...

Next
GroupMe Mobile App Wins SXSW Breakout Award
GroupMe Mobile App Wins SXSW Breakout Award

GroupMe for BlackBerry, collaborated with Xtreme Labs, won the Breakout Digital Trend Award at the South by...

Enter curious. Exit smarter.

Register Now