4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Gem を使わずにデコレータを作る

Posted at

はじめに

Rails にはデコレータを作るための代表的な Gem として DraperActiveDecorator があります。これらの Gem は Rails のモデルオブジェクトを View に特化したオブジェクトにデコレートすることを目的としています。これらは便利ですが、Rails の View 以外、あるいは Rails 以外で使うには、より汎用的な仕組みがほしいです。

実は Ruby の標準ライブラリにそのような仕組みが存在します。それが SimpleDelegator です。今回はこの SimpleDelegator を使ってデコレータを作ってみます。

SimpleDelegator を使ってデコレータクラスを作る方法は、SimpleDelegator を継承したクラスを用意するだけです。

class GirlDecorator < SimpleDelegator
  def full_name
    "#{last_name} #{first_name}"
  end
end
class Girl
  attr_reader :last_name, :first_name
  
  def initialize(last_name, first_name)
    @last_name = last_name
    @first_name = first_name
  end
end

girl = Girl.new('中川', '夏紀')

decorated_girl = GirlDecorator.new(girl)
decorated_girl.full_name #=> "中川 夏紀"

おまけ

次のようなモジュールを定義すると便利かもしれません (クラス間の結合度は上がりますが) 。

# クラス名 + Decorator という名前のデコレータクラスを定義していることが前提。
module Decoratable
  # Draper の API を真似て
  # デコレートされたオブジェクトを返すインスタンスメソッドを定義する。
  def decorate
    # Active Support を使っている場合は
    # Object.const_get の代わりに "#{self.class}Decorator".constantize で OK。
    decorator_class = Object.const_get("#{self.class}Decorator")
    decorator_class.new(self)
  end
end
class Girl
  include Decoratable
  
  attr_reader :last_name, :first_name
  
  def initialize(last_name, first_name)
    @last_name = last_name
    @first_name = first_name
  end
end

girl = Girl.new('中川', '夏紀')

decorated_girl = girl.decorate
decorated_girl.full_name #=> "中川 夏紀"
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?