Back to Tutorials
Jutsu>Rails|Tutorial6/8/2025

Ruby on Rails Delegate: Don't break the Law of Demeter !

I'm sure you know about the Law of Demeter. It's also known as the principle of least knowledge. Let's see how to apply it in Ruby on Rails !

If you don't know about it, let me explain it quicly. The law of Demeter is a programming guideline implying that an entity should only talk to its close friends. If we put in another way, an object should not call methods through another object.

When using Rails and the cool associations feature, it can be tempting to chain method calls like this:

product.provider.name
provider.address.city
company.building.city

These lines violate the Law of Demeter. To fix it, we should change them to be :

product.provider_name
provider.address_city #or provider.city
company.city

This way, it's much cleaner and we don't break the law anymore. But to do that, we need to add a bunch of methods to our models :

  class Product < ActiveRecord::Base
    belongs_to :provider

    def provider_name
      provider.name
    end

    # More methods to access the provider's attributes
  end

  class Provider < ActiveRecord::Base
    has_many :products

    # Has a name attribute
  end

You get the idea ! The models will grow out of control if we define methods for each attribute like this. But Rails has a solution : Delegate.

  class Product < ActiveRecord::Base
    belongs_to :provider

    delegate :name, to: :provider, prefix: true
  end

  class Provider < ActiveRecord::Base
    has_many :products

    # Has a name attribute
  end

Note the use of the prefix key. It allows us to use product.provider_name instead of just product.name since a product would probably have its own name.

Delegate is a really powerful feature that let you clean up your models. Let's see another example.

If we have a Company that belongs to a Building, we could do :

class Company < ActiveRecord::Base
  belongs_to :building

  delegate :street, :city, :country, to: :building, allow_nil: true
end

class Building < ActiveRecord::Base
  has_many :companies

  attr_accessible :street, :city, :country
end

Now, we don't break the law of Demeter anymore since we can access the street directly from the company object. Plus, less BS inside our models ;) Note how we added allow_nil to the delegate. With this little addition, if the company does not have any building associated, we will just get nil when calling street and no exception!

If you never used the delegate method, it's time to add it to your toolbox !

You can get more information about delegate in the documentation.

Comments

Loading comments...

Level Up Your Dev Skills & Income 💰💻

Learn how to sharpen your programming skills, monetize your expertise, and build a future-proof career — through freelancing, SaaS, digital products, or high-paying jobs.

Join 3,000+ developers learning how to earn more, improve their skills, and future-proof their careers.

Ruby on Rails Delegate: Don't break the Law of Demeter ! | Devmystify