2014/02/09

自分流 Rails での区分値

Railsでの区分値の扱いについて考える - TIM Labs
ActiveHashを使ってRailsで区分値を扱う方法 - TIM Labs

このあたりを読んでの話。

自分の場合は、もっぱらDBに保存する派です。
まあ、理由はいくつかあって

  • SQLで使いやすい
    過去のしごとで「アプリケーションの機能を作る程ではないけどこういう統計情報がほしい」という依頼を受けることがわりとあって、その時に画面表示と同じ文言を JOIN だけで出せる。
    区分が増えるほど CASE が増えていく SQL は書くのも保守するのもしんどい。
    Rubyを通さないと区分と文言の定義を正しく取れないのは使いづらい。
  • 区分を増やしてもアプリケーションの更新が必要ない場合がある
    区分値というのはドロップダウンリスト、チェックボックスのリスト、ラジオボタンのリストなどで画面から選択させることがよくあります。
    そんな場合、マスタ管理の機能を組み込むなり、INSERT実行するなりでアプリケーションの更新なしで対応できます。
    プログラム内で区分値を特定して使用する場合に初めてアプリケーションの更新が必要というのは理にかなってると思う。
  • 区分の保存先は統一したい
    数が少ない区分はコードで定義したほうが使いやすいが、付随する情報が多い区分はDBに保存したくなりません?
    でも保存先が分散されるのは保守しづらいのでどこかに統一したい。そんな場合、大は小を兼ねるでDBを選択してます。
というメリットが大きいな、使いやすいなと感じています。

でもDBに保存した場合、二重管理というのは確かに頭を悩ませる問題ですね。

def self.male
  find(id: 1)
end
みたいなコードを過去には量産してしまったりしてました。
それはやっぱりよろしくないので、自分の場合はちょっとした gem を作って対応してます。

pinzolo/mastar という gem で、以下その紹介。

countries
id name code
1 日本 japan
2 アメリカ合衆国 usa

こんなテーブルに対して、

class Country
  include Mastar
  mastar.key :code
end

とすれば、Country.japanfind(1) の結果にアクセスできます。
code のような、一意なコードを扱う列を作らなければいけないですが、二重管理からは開放されるので個人的には重宝してますね。
機能だけ作って README.md 書くのがめんどくさくなって v0.9.0 としてひっそりリリースして放置してました。
せっかくなので Country クラスのオブジェクトに対して japan? で判別できるメソッドが生える機能を足して v1.0.0 としてリリースしました。 もし使えそうなら使ってみてください。

あ、あと view でドロップダウンリストのために f.select :country_id, Country.all.map { |c| [c.name, c.id] } やら f.collection_select :country_id, Country.all, :id, :name と書いていたのを f.select :country_id, Country.pairs と書けるようにもなります。地味に気に入ってます。

0 件のコメント :

コメントを投稿