独自クラスをDraperを使ってdecorateする

はじめに

最近Draper使ってview周りのコードを書いてるんですが、ほんと素晴らしいですよねこのgem。
で、model以外でも使えたらもっと便利なのにな〜と思いながら色々調べていたら、Draper::Decoratableモジュールをincludeすれば何でもdecorateできるという記述があったので*1、早速検証してみました。

コード例

以下のコードは次のような設定になっています。

  • lib/ArticleというActiveModel::Modelをincludeした独自クラスが存在する
  • 同クラスをviewで扱う際のロジックをArticleDecoratorで定義する
# lib/article.rb
class Article
  include ActiveModel::Model
  include Draper::Decoratable

  attr_accessor :published_at
  validates :published_at, presence: true

  def published?
    valid? && published_at <= Date.today
  end
end
# app/decorators/article_decorator.rb
class ArticleDecorator < Draper::Decorator
  delegate_all

  def publication_status
    if published?
      "Published at #{published_at}"
    else
      "Unpublished"
    end
  end

  def published_at
    model.published_at.strftime("%A, %B %e")
  end
end

動作確認

Article.new(published_at: Date.today).decorate.publication_status
#=> "Published at Thursday, May 22"

Article.new(published_at: 1.day.from_now).decorate.publication_status
#=> "Unpublished"

ばっちりですね。

おわりに

Draper、ほんと便利なのでどんどん使っていきましょう。