Railsでenum+i18n
state_machineという便利なgemがあります。
カラムの状態、状態の別名とかを管理が出来て結構便利に使わせてもらっていたのですが、
もう2年程更新がされておらすRails4.2系だとエラーになる場合もあるようです(確実にエラーになるかまでは分かりません)。
そこでenum
色々調べるとRails4.1から入ったenumを使えばいいかも的な情報を見かけたので使ってみたところちょっと使いづらい。
Rails4 - ActiveRecord::Enum の使いドコロ - Qiita
enumの追加の順番が大事なのはCでも同じなので、ある程度熟練したプログラマなら問題にはしません。
今どきC時代と同じ対応が必要なのは微妙な気はしますけど。
問題はi18n。
この対応が出来ない。あくまでも値の別名を付けやすくするだけの機能なのでしょうがないとは思いますがちょっと不親切です。
enum_helpという選択肢も示されていますし、検索すると他のgemも提案されているようではあります。
しかし、gemの問題はstate_machineのように更新されなくなったら終わりなのです。
gemに限らずcpanやらeasy_installのような類似の場合も同じ。
そこで個人的には、deviseのようなほぼ必須であったり、安定して信頼できるのでも無い限りは自作するべきと思っています。
仕事だとそうも行かない場合もありますが...
enum + i18n
ということで、今回はenumのi18n対応は自作しました。
はじめに考えたのはARを拡張するかどうか。
ARを拡張してlibあたりに置いておいてauto loadしておけば楽といえば楽なんですが、使わないmodelでもロードされるのは少し気持ち悪い。
そこで、model/concernsを採用しました。明示的にincludeしておけば分かりやすいですし。
Userモデルをサンプルにします。
# app/models/user.rb # 削除フラグdeletedがあると仮定する class User < ActiveRecord::Base enum deleted:[deleted_off, deleted_on] end
i18n辞書にはこのように書いておきます
ja: states: users: deleted: deleted_off: '未削除' deleted_on: '削除済'
model/concerns以下に好きなファイルをおいておきます。
# このメソッドをconcernsに置いておく # model側でのincludeも忘れずに def state_machine_human(column) state = self.try(column) return "#{column}" if state.blank? I18n.t('states.' + self.class.table_name + '.' + column + '.' + state) end # 使い方 user = User.all.first user.state_machine_human('deleted')
これで使えるはずです。concernsって便利!
missing_method使えばもっと良いメソッド名とかにも出来るとは思います。
まとめ
gemは便利ですが、この程度であればわざわざgemを使うよりも作ったほうがよいでしょうね。
仕事だと特に作成者とメンテナが違うという事だって珍しくありません。
技術は適切に使いましょう。動けば良いのと、管理しやすいのは別問題ですよね。