ActiveRecordの便利機能delegate

delegateはメソッドを異なるクラス間で簡単に使えるようにできます。

実装

Articleクラスは関連付としてcategoryとauthorを持っているとします。categoryにはname,slug authorにはnameカラムがあって参照できます。

article.category.nameのように名前を呼び出したい時があって、毎回メソッドチェーンしたものを書くと冗長に感じますよね。

なのでArticleクラスに name,slugメソッドを定義するとします。 以下のようなコードになります。 article.rb

class Article < ApplicationRecord
  belongs_to :category

def category
  article.name
end

def category
  article.slug
end

def author
  article.name
end


category.rb

class Category < Taxonomy
  has_many :articles
end


delegateなしだと、カテゴリーのnameとslug、著者のnameを取得しようとすると、上のようにcategoryとauthor越しに取得しなければいけない。

ここでdelegateの出番!delegateを使ってあげることで、短く書くことができます。
article.rb

class Article < ApplicationRecord
  belongs_to :category
 

  delegate :name, to: :category, prefix: true, allow_nil: true
  delegate :slug, to: :category, prefix: true, allow_nil: true
  delegate :name, to: :author, prefix: true, allow_nil: true


prefixとallow_nilについて

prefix

prefix:trueにすることによって、マクロによってnameの代わりにcategory_nameが生成されます。

こうすることでarticle.category_nameで呼び出すことができます。


allow_nil

委譲時にNoMethodErrorが発生して対象がnilの場合、例外が発生します。:allow_nilオプションを使うと、例外の代りにnilを返すようにすることができます。


参考URL

railsguides.jp