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-friendlyperson.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 saybusiness.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
More Content by Pivotal Labs