Gemfile · I codes and I blogs

Learn to delegate (your model methods)

delegate is neat trick that allows one to write cleaner, neater code. Particularly when dealing with ActiveRecord associations, delegate makes it possible to “outsource” a method to an associated object.

class Book < ActiveRecord::Base
  # has attribute 'author'
end

class Chapter < ActiveRecord::Base
  belongs_to :book
  delegate :author, to: :book
end

Without delegate, when dealing with a Chapter object, you’d need to access the book’s author via chapter.book.author. With delegation, this can be neatly shortened to chapter.author, with the .author getting handed off to the associated Book object.

An object can delegate multiple methods to its association, as shown in the example below. Another handy option is to use prefixes with delegate. For instance, using the same approach as above to refer to the book’s title would create chapter.title, which is confusing. With prefixes, however:

class Chapter < ActiveRecord::Base
  belongs_to :book
  delegate :author, :title, to: :book, prefix: true
end

chapter.book_title   # returns book's title
chapter.book_author  # returns book's author

(Of course, if chapters had their own titles, the above code would make them inaccessible, but that’s what you get with contrived examples. See this post on the Pivotal Labs’ blog for a solution.)

One final tidbit to touch upon is that delegate is not limited to deliberately created methods and attributes but extends equally well to those created behind the scenes by the association:

class Quote < ActiveRecord::Base
  belongs_to :chapter
  delegate :book, to: :chapter
end

quote.book  # returns the book object associated with the chapter to which the quote belongs

For more on delegate, including custom prefixes and how to handle NoMethodErrors, see the API Docs.