No commit activity in last 3 years
No release in over 3 years
define ActiveRecord constants with DSL.and more!
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 3.0.0
>= 1.0.0
>= 1.8.3
>= 3.12
>= 2.8.0

Runtime

>= 3.0.0
 Project Readme

const_enum¶ ↑

ActiveRecordの定数クラス、定数名アクセサ、NamedScope、定数値判定メソッド等を簡単なDSLで作成するためのライブラリ。ActiveRecord3.xに対応しています。

インストール¶ ↑

Gemfileに以下の行を追加して、bundle installコマンドを実行してください。

gem 'const_enum'

あるいは、以下のコマンドでインストールしてください。

gem install const_enum

設定¶ ↑

定数のラベル定義ファイルを作成¶ ↑

# config/locales/labels_ja.yml
 ja:
   labels:
     user:
       status:
         disable: "無効"
         enable:  "有効"

constメソッドのブロック内で定数を定義¶ ↑

class User < ActiveRecord::Base
  const :STATUS do
    ENABLE    1
    DISABLE   0
  end
end

使用例¶ ↑

定数値へのアクセス¶ ↑

User::STATUS::ENABLE  # 1
User::STATUS::DISABLE # 0

ActiveRecordの拡張¶ ↑

# データを作成
taro   = User.create(:name => 'taro'  , :status => Hoge::STATUS::ENABLE)
hanako = User.create(:name => 'hanako', :status => Hoge::STATUS::DISABLE)

# {ATTR}_labelメソッドが定義される
taro.status_label   # "有効"
hanako.status_label # "無効"

# {ATTR}_{CONST}?メソッドが定義される
taro.status_enable?  # true
taro.status_disable? # false

# was_{ATTR}_{CONST}? ,  #{ATTR}_{CONST}_wasメソッドが定義される
taro.status = User::STATUS::DISABLE
taro.status_enable?      # false
taro.was_status_enable?  # true
taro.status_label_was?   # 有効

# named_scopeが定義される
User.status_enable.all

Validationでの利用¶ ↑

constメソッドで定義される定数クラスはinclude?メソッドを実装しているため、validates :inclusionで利用することができる。

class User < ActiveRecord::Base
  const :STATUS do
    ENABLE    1
    DISABLE   0
  end
  validates :status, :inclusion => {:in => STATUS}
end

Viewでの利用¶ ↑

constメソッドで定義される定数クラスはEnumerableモジュールをインクルードしているため、collection_selectにそのまま渡すことができる。値はvalue、ラベル名labelメソッドを指定する。

user = User.new
form_for user do |f|
  f.collection_select(:status, User::STATUS, :value, :label)
end

定数オブジェクトへのアクセス¶ ↑

{Class}::ATTRで各定数オブジェクトにアクセス可能

User::STATUS[1].class # User::STATUS
User::STATUS[1].value # 1
User::STATUS[1].label # "有効"

ActiveRecord::Base.constメソッドのオプション¶ ↑

prefix: NamedScope、属性値テストメソッドの名前を変更する¶ ↑

constメソッドにprefixオプションを指定することで、作成されるNamedScope、属性値検証メソッドの名前(プレフィクス)を変更することができる。定数値名がモデル内で衝突しない場合は、prefixに空文字を与えるのが使いやすい。

class User < ActiveRecord::Base
  const :STATUS, :prefix => '' do
    ENABLE    1
    DISABLE   0
  end
end

user = User.enable.first
user.enable?  # true
user.disable? # false

scope: NamedScopeを作成しない¶ ↑

値が直接DBにない場合、scopeオプションでfalseを指定すると、定数値を返すメソッドを定義することで各種メソッドを利用できる。

class Entry < ActiveRecord::Base
  # 公開状態[予約、公開、終了]
  const :STATUS, :scope => false, :prefix => '' do
    SCHEDULED 1
    OPENED    2
    FINISHED  3
  end

  scope :scheduled ,lambda {time = Time.now; where('start_at > ? ', time) }
  scope :opened,    lambda {time = Time.now; where('start_at <= ? AND end_at > ?', time, time) }
  scope :finished,  lambda {time = Time.now; where('end_at <= ? ', time) }

  # 公開状態
  def status
    now = Time.now
    case
    when start_at > now
      STATUS::SCHEDULED
    when (end_at >= now and start_at <= now)
      STATUS::OPENED
    else
      STATUS::FINISHED
    end
  end

  # 変更前公開状態
  # status_label_wasやwas_opened?などを使わない場合は不要
  def status_was
    now = Time.now
    case
    when start_at_was > now
      STATUS::SCHEDULED
    when (end_at_was >= now and start_at_was <= now)
      STATUS::OPENED
    else
      STATUS::FINISHED
    end
  end
end

entry = Entry.create(:start_at => Time.now, :end_at => Time.now + 10.days)
entry.status_label
entry.active?

predicate: 属性値テストメソッドを作成しない¶ ↑

predicateオプションでfalseを指定すると、属性値テストメソッドの作成が行われない。

i18n: ラベル名にi18nを利用しない¶ ↑

i18nオプションでfalseを指定すると、constメソッド内の定数値定義の後にラベル名を与えることでラベル名を定義することができる。

# app/models/user.rb
class User < ActiveRecord::Base
  const :STATUS, :i18n => false do
    ENABLE    1, "有効"
    DISABLE   0, "無効"
  end
end

extensions: 定数オブジェクトに追加のメソッドを定義する¶ ↑

ブロック内にメソッド定義を書くと、STAUTS[]やSTATUS.eachの際に取得できる定数オブジェクトに対してメソッドが定義される。collection_selectの際に表示したいラベル名を複数パターン用意する場合などに利用可能。

class User < ActiveRecord::Base
  const :STATUS do
    ENABLE    1
    DISABLE   0
    # 定数オブジェクトには以下のメソッドが存在するため、これらのメソッドを自由に呼び出すことができる
    # key   名前空間(クラス、モジュール名)を含まない各定数名のシンボル
    # label ラベル名
    # value 定数値
    def code
      '%05d'%value
    end
    # I18nを使ってみる。
    def label2
      I18n.t(key.to_s.downcase, :scope=> 'labels.user.status_label2')
    end
  end
end

# 選択肢に上で定義したcodeメソッドの値を使用する
user = User.new
form_for user do |f|
  f.collection_select(:status, User::STATUS, :value, :code)
  f.collection_select(:status, User::STATUS, :value, :label2)
end

その他¶ ↑

デフォルトでI18nを無効にする¶ ↑

ConstEnum::ActiveRecord.i18nにfalseを設定すると、constメソッドのi18nオプションの初期値をfalseにすることができます。

# config/initializers/const_enum.rb
ConstEnum::ActiveRecord.i18n = false

# app/models/user.rb
class User < ActiveRecord::Base
  const :STATUS, :prefix => '' do
    ENABLE    1, "有効"
    DISABLE   0, "無効"
  end
end

ラベル名を取得するメソッド名を変更する¶ ↑

ConstEnum::ActiveRecord.label_suffixを設定することで、ラベル名を取得すためのメソッドの名前(サフィックス)を変更することができる。

# config/initializers/const_enum.rb
ConstEnum::ActiveRecord.label_suffix = '_name' # ラベル名を返すメソッドにつけるサフィックスの指定

Copyright © 2012 Synergy Marketing, Inc. See LICENSE for details.