railsのmodel内で擬似enum

rails4.1くらいからenumをmodel内で再現できるようになったらしい。

ActiveRecord::Enum

実際に試してみたのだけれど、なかなか便利。なるほど、これは使えそう。

class Filament < ActiveRecord::Base

  enum material: { abs: 0, pla: 1, plaster: 2, akryl: 3, nylon: 4, titanium: 5, maragingMetal: 6, inconeAlloy: 7 }

end

こんな感じ。一瞬で書けるし便利。

しかし、結構大きな弱点もあって、当然、Modelname.methodnameみたいになる都合上、スペースとかは入れられない。僕がやりたかったのは、どちらかというとEnumというよりArrayで配列と対応付けする、ということをmodel内で簡単に管理することだったんで、

modelクラスの中でのselfの使い方 - Rails つまみぐい

を参考にしながら、以下のようなコードを生成してみた。

class Filament < ActiveRecord::Base

  class << self
  def material_types
    material_types = { 
      0 => "ABS",
      1 => "PLA",
      2 => "Plaster",
      3 => "Akryl",
      4 => "Nylon",
      5 => "Titanium",
      6 => "Maraging Metal",
      7 => "Incone Alloy"
    }   
    material_types
  end

  def material_type
    selfs.class.material_types[self.material]
  end

end

こうすれば、Filament.material_typesでセレクトボックスにも使えそうな配列を入手できるし、Filamentのインスタンス.material_typeで実際にそのインスタンスのmaterial_typeを返してくれるし、便利。

enumのためのgemはいくつかあるようだけれど、ぶっちゃけmethodname! / methodname?とか自分で書くの面倒な人には便利かもだけれど、それじゃやりすぎな時もあるなあと思うなど。