サーチ…


備考

デコレータパターンを使用すると、ベースオブジェクトに影響を与えずに、状況に応じてオブジェクトの動作を追加または変更できます。

これは、stdlibを使用する単純なRubyやDraperのような一般的な宝石を介して達成できます。

SimpleDelegatorを使用したモデルの装飾

ほとんどのRails開発者は、テンプレート自体のモデル情報を変更することから始めます。

<h1><%= "#{ @user.first_name } #{ @user.last_name }" %></h1>
<h3>joined: <%= @user.created_at.in_time_zone(current_user.timezone).strftime("%A, %d %b %Y %l:%M %p") %></h3>

多くのデータを持つモデルの場合、これはすぐに煩雑になり、あるテンプレートから別のテンプレートにロジックをコピー・ペーストすることにつながります。

この例では、stdlibのSimpleDelegatorを使用しています。

SimpleDelegatorオブジェクトへのすべての要求は、デフォルトで親オブジェクトに渡されます。プレゼンテーションロジックで任意のメソッドをオーバーライドすることも、このビューに固有の新しいメソッドを追加することもできます。

SimpleDelegator 2つのメソッドを提供します。 __setobj__に委任されているものを対象設定、およびする__getobj__そのオブジェクトを取得します。

class UserDecorator < SimpleDelegator
  attr_reader :view
  def initialize(user, view)
    __setobj__ @user
    @view = view
  end

  # new methods can call methods on the parent implicitly
  def full_name
    "#{ first_name } #{ last_name }"
  end

  # however, if you're overriding an existing method you need
  # to use __getobj__
  def created_at
    Time.use_zone(view.current_user.timezone) do
      __getobj__.created_at.strftime("%A, %d %b %Y %l:%M %p")
    end
  end
end

いくつかのデコレータは、この動作をワイヤリングするために魔法に依存していますが、ページ上のオブジェクトを初期化することによってプレゼンテーションロジックがどこから来ているのかをより明確にすることができます。

<% user = UserDecorator.new(@user, self) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>

ビュー・オブジェクトへの参照をデコレータに渡すことで、プレゼンテーション・ロジックを組み込むことなく、ビュー・ヘルパの残りの部分にアクセスすることができます。

これで、ビューテンプレートはページにデータを挿入することのみに関心があり、はるかに明確です。

Draperを使ったモデルの装飾

Draperは、コンベンションによってモデルをデコレータと自動的にマッチングさせます。

# app/decorators/user_decorator.rb
class UserDecorator < Draper::Decorator
  def full_name
    "#{object.first_name} #{object.last_name}"
  end

  def created_at
    Time.use_zone(h.current_user.timezone) do
      object.created_at.strftime("%A, %d %b %Y %l:%M %p")
    end
  end
end

ActiveRecordオブジェクトを含む@user変数を指定すると、 @user#decorateを呼び出すことによってデコレータにアクセスしたり、固有のものにしたい場合にDraperクラスを指定してデコレータにアクセスできます。

<% user = @user.decorate %><!-- OR -->
<% user = UserDecorator.decorate(@user) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow