SakuraWi - BLog

WEBエンジニア。聴いたお話をまとめておく倉庫的な。スタックストックスタック!

【Ruby on Rails】delegateの使い方【委譲は便利】


Ruby on Railsにおける便利なメソッドとして、 delegateがあります。

こちらを使うと、メソッドチェーンをたくさん書く必要なく実装することができます。

忘れずにrails guideのリンクも置いておきます。

Active Support コア拡張機能 - Rails ガイド

delegateの使い方

いつも書き方を忘れてしまうため、まずは利用例から書きます。

書き方としてはこのように書きます。

delegate :method_name, to: :associtation

覚えておくのは、delegate :aaaのようにかけば @instance.aaaと呼べるようになると認識しておくとよいと思います。

to:で書いた部分を省略できるというイメージです。

@instance.assoctiona.aaa と書いていた部分を、 @instance.aaaで呼べます。

delegateの実例

クラスの例としては User, Profileクラスがあるとしましょう。(railsガイドと同様の例にしました)

Userクラスは関連付けとして profileを持っているとします。 Profileにはnameカラムがあって参照できるとします。

class User < ApplicationRecord
  has_one :profile
end

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

と、いうことで Userクラスに nameメソッドを定義するとします。 以下のようなコードになるでしょう。

class User < ApplicationRecord
  has_one :profile
 
  def name
    profile.name
  end
end

これでも良いんですが、もっと簡潔に書く方法が delegateです。

@user.nameと呼び出すことが下記の書き方でも実現できます。

class User < ApplicationRecord
  has_one :profile
 
  delegate :name, to: :profile
end

より明示的かつ、短く書くことができました。

インスタンス変数や定数へもアクセスが可能

delegateする対象ですが、インスタンス変数へアクセスすることも可能です。

delegate to:@user

また、定数を参照することも可能。 定数はそのままクラスメソッドのように呼び出せるのであまり使うケースは少なそうに思います。

delegate to: :NUMBER

option

オプションとして、prefixをつけることも可能です。

delegate to: :method_name, prefix: :aaa

上記のように書くと、メソッドを呼び出すときに以下のように呼び出すことができます。

@instance.aaa_method_name

allow_nil

delegate :name, to: :profile, allow_nil: true

上記のように :allow_nilオプションを付与すると、間のprofileがnilだった場合に、

@user.name は例外ではなく、nilを返すようにできます

  def name
    profile&.name
  end

のようにぼっち演算子をつけたメソッドを定義した感じですね。