LoginSignup
15
15

More than 5 years have passed since last update.

enumとi18nとactive_decoratorで表示処理がスッキリ

Last updated at Posted at 2015-07-20

はじめに

モデルの状態を表す日本語文字列をどこにおくべきか迷ってました。
同僚からi18nenumactive_decoratorを使うことを提案されて、試してみたらもやもやが晴れたのでまとめました。

環境

enumはrails4.1から導入されたので、それ以降ならたぶん大丈夫です。

なんかもっさりしたコード

app/models/article.rb
class Article < ActiveRecord::Base
  STATUS_DRAFT = 0
  STATUS_PUBLIC = 1
  STATUS_DISABLED_BY_ADMIN = 2

  STATUS_LABELS = {
    STATUS_DRAFT => "下書き",
    STATUS_PUBLIC => "公開中",
    STATUS_DISABLED_BY_ADMIN => "管理者により非公開中",
  }

  def active?
    status == STATUS_PUBLIC
  end

  def status_label
    STATUS_LABELS[status]
  end
end

ステータスを数値型にしています。
ステータス値を意味ある文字列で扱えるように、定数を定義したり、
ビューでの表示用の日本語ラベルを定義したりしています。
いろいろモデルに固まってて、微妙でした。

書きなおしたコード

app/models/article.rb
class Article < ActiveRecord::Base
  enum status: { draft: 0, opened: 1, closed_by_admin: 2 }

  def active?
    opened?
  end
end

ステータスをenumで定義して…

config/application.rb
config.i18n.default_locale = :ja

デフォルトのロケールをjaにして…

config/locales/application_ja.yml
ja:
  articles:
    statuses:
      draft: 下書き
      opened: 公開中
      closed_by_admin: 管理者により非公開中

モデル内で定義してあった日本語ラベルをi18nに移して…

gem "active_decorator"

active_decoratorを導入して…

app/decorators/artcible.rb
module ArticleDecorator
  def status_label
    t("articles.statuses.#{status}")
  end

  def status_labels
    Article.statuses.map {|k, v| [t("articles.statuses.#{k}"), k] }
  end
end

ビューでだけ使いそうなラベル表示用のメソッドをdecoratorに移しました。

気持ちよくなったところ

  • 自分で作らなくても、ステータス設定や問い合わせが#opened!#opened?でできること
  • 日本語の定数がモデルから排除できたこと
  • 表示用のメソッドをモデルから排除できたこと
15
15
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
15
15