Rails : use delegate to avoid long method chains

29 Aug 2013

Consider you have two tables products and Oraganisation, where product belongs to a particular organisation.

Product                   Organisation
  - id                      - id
  - name                    - name
  - organisation_id         - description

So when you want to get the organisation name, which the product belongs to then you say,

 # Please note that thoughtout this post I will be refereing to `@product` which 
 # assumed as object of Product model.
@product.organisation.name

But according to “Rails Anti-patterns” more than one dot notation in a statement is an example of anti pattern.

Normal fix

So How we can fix it, In Product model write a instance method organisation_name just like below.

class Product < ActiveRecord::Base
  belongs_to :organisation

  def organisation_name
    organisation.name
  end
end

Using delegate

Writing methods for all the properties is a tedious task, Instead of that we can use delegate in rails.

You can simply use below code instead of writing a method organisation_name.

class Product < ActiveRecord::Base
  belongs_to :organisation

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

Now you can use @product.organisation_name to instead of @product.organisation.name.

You can pass method name and target model/object via :to option. Here :prefix option determine whether the method name should prepend with object name or not.

If you wanna custom prefix, then

class Product < ActiveRecord::Base
  belongs_to :organisation

  delegate :name, to: :organisation, prefix: :org
end

Now you can use as @product.org_name

If you find my work helpful, You can buy me a coffee.