QA@IT

ActiveRecord でモデルに雑多な設定情報を持たせるには

2642 PV

ユーザごとに設定情報を保存できるようにしたいという場面はよくあるかと思います。独立したテーブルを作るには大袈裟で、とはいえ1つのカラムに serialize して突っ込むと入力値のチェックや型変換が煩雑になって大変悩ましいのですが、何かクールなソリューションはないものでしょうか。

設定項目は例えばこんなデータです:

{
  timezone: '+0900',
  show_thumbnail: true,
  web_notifications: {
    mention: {
      enabled: true,
      timeout: 5
    },
    ...
  },
  ...
}

ActiveRecord::Store を使ってみたところ、設定の更新時に params 中の数値や真偽値を変換するのがめんどくさすぎて挫折しました。Hash に対する変換ルールを宣言的に定義できるライブラリとかがあればよさそうと思いましたが、特に手段は問いません。

回答

StoreConfigurableなんかどうでしょう。

StoreConfigurable: https://github.com/metaskills/store_configurable

あと、真偽値を扱う要素の比率が大きいなら、実はHashよりSet型のほうが便利だったりすることも多いとおもいます。もしそうであるならば、拙作ですが、

StoreField: https://github.com/kenn/store_field

なんかも参考になるところがあるかもしれません。

一点気をつけたいところとしては、serializeされているカラムは(破壊的操作を検出できないため)dirty判定がスキップされてsave時に必ずUPDATEが走るという問題です。つっこむデータの大きさ・更新頻度に気をつけたいところです。

これを回避するためには、どのモデルからでも共通で使えるpolymorphicな専用テーブル(id, configurable_type, configurable_id, dataな4カラムのイメージ)を用意して更新の必要なときだけこちらをsaveするするなどの工夫が必要です。ちなみに、StoreConfigurableのほうでは頑張ってDirtyにも対応しているようです。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。