ルビーでのデリゲートパターンの使用方法


Ruby on Railsアプリケーションのより複雑な関連付けで作業するときは、ビューまたはヘルパーにデータをレンダリングするときにオブジェクト連鎖問題に自分自身を見つけることができます.デリゲートパターンはRuby on Railsに便利な組み込み機能です.

何が正確に代表ですか?
より深い観察at the Ruby on Rails API documentation あなたは、あなた自身のものとして簡単に包含されたオブジェクトの公開メソッドを公開するのに使用されるRubyクラスメソッドとして定義されたデリゲートを見ることができます.
それはより複雑に聞こえるし、幸運にも設定するのは簡単です.
この例では、このチュートリアルではUser モデルとProfile このパターンを示すモデル.あなたは何かに沿って従うように似ている必要がありますが、ほとんど何も関係なく、十分に必要があります.
side note :私のRailsアプリケーションテンプレートを参照Kickoff Tailwind ビデオで.このテンプレートはUser モデル自動的に私たちのための便利なおかげでDevise ジェム.
あなたがテンプレートを持っていないか、それを気にしたくないならば、あなたはあなたのアプリに加えられる基本的なユーザーモデルを得るためにこれを走らせることができます:
rails generate model User first_name:string last_name:string email:string
プロファイルモデルを作成するには、次の手順を実行します
rails generate Profile tagline user:references
rails db:migrate
両方のモデルを作成すると、いくつかのダミーデータが必要です.私はレバレッジrails console 手でいくつかを作成します.
rails console
だってmy template 先取特権Devise 新しいユーザを作成するために必要なオブジェクトデータを作成します.
# if you're using my template/devise
> User.create({name: "Andy Leverenz", email: "[email protected]", password: "password", password_confirmation: "password"})

# if you're not using my template/devise
> User.create({first_name: "Andy", last_name: "Leverenz", email: "[email protected]"})
そして今、いくつかのプロファイルデータ
> Profile.create(tagline: "My awesome profile", user_id: User.first.id)
ここで参照User 私たちはちょうどあなたのデータベースで作成された最初のユーザーを作成しました.あなたはより便利に次のように実行することができますし、ActiveRecordマジック内蔵のものが自動的に物事を説明する必要があります.
> Profile.create(tagline: "My awesome profile", user: User.first)

関係
我々のモデルとデータを作成すると、我々のモデルを確保するために必要な成功を設定する必要があります.

ユーザモデル
私たちのユーザーモデルは、それが最初に作成されたときに我々の発電機のおかげで注意する必要があります.私のファイルはこのように見えます.もう一度、私はテンプレートを使用しますので、あなたがそれを使用していないならば、あなたのマイレージは変化するかもしれません.
# app/models/user.rb
class User < ApplicationRecord
  has_person_name
  has_one :profile

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
end

各ユーザーは、これまでのアカウントには、このアプリでは1つのプロファイルを持っているので、我々は、行を読むことを確立しますhas_one :profile .

プロファイルモデル
The Profile モデルはとても簡単です.
class Profile < ApplicationRecord
  belongs_to :user
end
何故ならUser has_one :profile エーProfile ニーズbelong_to ユーザ.

委任の追加
この時点で、我々は我々のアプリを使用して離れてコード化し、プロファイルビューにいくつかのデータをレンダリングすると言うなら、我々はこのようにアクセスする必要があります@profile.user.name . その連鎖効果は、大きな取引ではないが、それを持っている必要はありません.user 真ん中や名前を完全に別のものとして参照してください.
デリゲートを使用してこれらのものを含めるようにプロファイルモデルを拡張できます.
ユーザーモデルの場合、プロファイルにいくつかのメソッドを委任できます.`ruby
class User < ApplicationRecord
has_person_name
has_one :profile

delegate :username, to: :profile
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable

def username
"#{first_name}_#{last_name}"
end
end
`

Here I create a new username クラスから成るクラスメソッドfirst_name and last_name 属性User データベース層の表.その方法は、私たちはdelegate メソッドを指定し、Profile モデル.`ruby
class Profile < ApplicationRecord
belongs_to :user

delegate :username, :email, to: :user, allow_nil: true, prefix: :user
end
`

On the Profile 我々が使う側delegate クラスメソッドを渡す方法User 我々が我々のアクセスを望むモデルUser モデルインサイドProfile モデル.
The delegate オプションで渡すことができますallow_nilprefix 同様に.
最終的には、カスタムの方法でデータを問い合わせることができます.`bash
rails c

profile = Profile.first
profile.email #= "[email protected]"
profile.username #= "Andy_Leverenz"
`

Pretty handy!

As an application scale, I can see this pattern being useful in terms of scoping and productivity.

I haven't seen it widely in use myself but I think it may be due to these invented naming conventions that aren't always obvious from one developer to the next on a team. The next developer that comes along might be looking for a database column named after some custom public method you made for delegation purposes and spend a lot of time trying to pinpoint its origin.

It has its pros and cons but looks really appealing for some applications. You be the judge!

Shameless plug!

Are you new to Ruby on Rails? Would you like an in-depth jumpstart to your learning experience? I made a comprehensive course to assist with that.

Find out more at hellorails.io