delegate

delegate provides a delegate class method to easily expose contained objects’ public methods as your own. Simply say, through delegation you can use public methods in other model directly.

For example I have a QueueItem and aVideo model.

QueueItem < ActiveRecord::Base
  belongs_to :video
end

Video < ActiveRecord::Base
  has_many :queue_items
  belongs_to :category
end

If I want to get the category object of the video in first queue_item, I may write

queue_item = QueueItem.first
queue_item.video.category.name
#=> "Action"

It is kind of cumbersome. Instead of getting the object via model association, we can use delegate to help us.

class QueueItem < ActiveRecord::Base
  belongs_to :video

  delegate :category, to: :video
end

Then we can get the category by

queue_item = QueueItem.first
queue_item.category.name
#=> "Action"

Or even you can set acategory_namemethod in the QueueItemmodel.

class QueueItem < ActiveRecord::Base
  belongs_to :video

  delegate :category, to: :video
  def category_name
    category.name
  end
end

queue_item = QueueItem.first
queue_item.category_name
#=> "Action"

You can set one or more method names (specified as symbols or strings) if you want. And the name of the target object via the :tooption(also a symbol or string).

There are some options you can use in delegation .

  • :to — Specifies the target object
  • :prefix — Prefixes the new method with the target name or a custom prefix
  • :allow_nil — if set to true, prevents a NoMethodError to be raised

You can use the prefix option to make the method more readable.

class QueueItem < ActiveRecord::Base
  belongs_to :video
  delegate :category, to: :video
  delegate :title, to: :video, prefix: :video
end

queue_item = QueueItem.first
queue_item.video_title == queue_item.video.title
# => true

Resource: rails/Module/delegate

results matching ""

    No results matching ""