2009年10月29日

RailsでReadonlyなmodel

Railsで更新は別のアプリが担当しているなどの理由で、読み取り専用でテーブルにアクセスしたい時がありますが、残念ながらRails自体には読み取り専用のモデルを作成する手段は無いようです。

と言うわけで、代替手段を探していたのですが、どうもスマートな手段が無く結局、readonly?メソッドを上書きして常にtrueを返すようにして、凌ぐようにしました。

ただ、それだけだと削除などが有効なため、結局以下のように一部メソッドでは直接ActiveRecord::ReadOnlyRecordをraiseしています。

以下、サンプルコードです

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Hoge < ActiveRecord::Base
  # 全レコードをReadOnlyということにしてCreate、Update系を阻害
  def readonly?
    return true
  end
 
  # テーブル自体の破壊を例外を返して阻止
  def before_destroy
    raise ActiveRecord::ReadOnlyRecord
  end
 
  # レコードの削除の際はreadonly?を確認しないようなので例外を返して阻止
  def self.delete(id)
    raise ActiveRecord::ReadOnlyRecord
  end
  def self.delete_all(conditions)
    raise ActiveRecord::ReadOnlyRecord
  end
  def self.delete_all!(conditions)
    raise ActiveRecord::ReadOnlyRecord
  end
end
なお、最後のdelete_all!メソッドは論理削除プラグインであるを導入してない場合は定義不要です。

ただ、あまりにも泥臭いのでもっと良い方法があるのかも知れませんし、リードオンリーにするためのPlug-inがあるのかもしれません。
(と言うか、あるのならぜひ教えてくださいm(_ _)m)

また、もし上記のサンプルコードを使う場合は、他のプラグインの影響や考慮漏れも考えられますので詳細なテストと、可能ならユーザを分けてテーブル単位でアクセス制限を行うことを推奨いたします。

Posted by Takuchan at 2009年10月29日 21:46 | トラックバック(0)