Ruby

【Rails】delegateで省エネする方法を、公式リファレンスから理解する

コードリーディングする時は、仮説立てて読むとスラスラ読めると最近気づきました。

バートリーのさいとうです。

今回は

delegateで省エネする方法

について、公式リファレンスを元に解説していきます。

delegate自体は、そこまで難しい概念ではありませんが、delegateを使いこなせると

  • アソシエーションを利用したメソッドの呼び出しを、簡略化して行える
  • メソッドの移譲ができる

というメリットがあります。

そのdelegateについて、アウトプット経験豊富なrails実務経験者が

  • delegateの使い方
  • delegateの用法
  • 少し応用的な使い方(メソッドにカラムを指定する)

の3点に絞って解説していきます。

参考↓

delegateで出来ること

delegateは、日本語で委譲・委任という意味です。

なので、言葉の通り、移譲ができます。では、何を移譲するのでしょうか?

答えはメソッドです。

具体例

例を見てみましょう。

今回扱うモデル

関連付けされているUserモデルとArticleモデルが存在するとします。

例として関連付けを出しているのは、delegateが関連付けしてないと利用できない仕組みだからです。

class User < ActiveRecord::Base
  has_many :articles
end
class Article < ActiveRecord::Base
  belongs_to :user
end

User has many articles

Article belongs to user

の関係です。

実際の使い方

例えば、Userに保存されているnicknameカラムがあるとします。

何もしなければ

user = User.new(nickname: "さいとう")
article = Article.new(user_id: user.id)
p article.user.nickname => "さいとう"

と記述することでarticleに紐づくuserのnameカラムの値を取れます。

さらに、以下のようにモデルにメソッドを記述すると、もっと簡単に取得することもできます。

class Articles < ActiveRecord::Base
  belongs_to :user

  def nickname 
    user.nickname
  end
end

user = User.new(nickname: "さいとう")
article = Article.new(user_id: user.id)
p article.nickname => "さいとう"

そして、さらにさらに短く1行で書く方法があります。

それがdelegateです。

class Articles < ActiveRecord::Base
  belongs_to :user

  delegate :nickname, to: :user
end

user = User.new(nickname: "さいとう")
article = Article.new(user_id: user.id)
p article.nickname => "さいとう"

以上が、delegateの基本的な使い方です。

書き方は

delegate :メソッド名(カラム名), to: :関連付けしているモデル名

が基本の形になります。

もちろん、指定したいカラムやメソッドが複数あるなら

delegate :nickname, :age, :sex, :first_name, :last_name, to: :user

のように指定できます。

ちょっと注意点

基本的には、以上のようにそこまで複雑な使い方はしていません。

しかし、一点だけ注意が必要なことがあります。

基本はパブリックメソッド

公式リファレンスによると、delegateの定義として

Provides a delegate class method to easily expose contained objects’ public methods as your own.

英語で書いてあるのでわかりにくいですが、大切なことは「パブリックメソッドとして定義するで〜」ってことです。

つまり、もしい大切なデータなどを指定してしまうと、(確率は低いと思いますが)いざって時に、面倒なことが起きかねません。

そこで、privateメソッドとしてdelegateを定義することが可能になっています。

やり方は、オプションでprivate: trueを付与するだけです。

delegate :date_of_birth, to: :profile, private: true

これで

private

def date_of_birth
  user.date_of_birth
end

と同義になり、アクセスできる範囲を狭めることが可能です。

内容のまとめ
  • delegateは、関連付け(アソシエーションが組まれている)の状態で利用することができる省エネ技
  • カラムを指定すると、省エネでアソシエーションを利用した取得が可能になる
  • パブリックメソッドとして定義される

まとめ

今回は、railsのdelegateの使い方、カラムを指定する方法を紹介しました。

少しでも参考になれば嬉しいです。

このように、月に15本目標で、Ruby, Ruby on Railsを中心に技術ブログを更新しています。

もし参考になったなと思ったら、ブックマークをお願い致します。

最後まで読んでいただき、ありがとうございました!

それでは。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA