2009-08-25 8 views
3

モデルのステータスを実装する際に問題が発生しています。これは恐らく誤った設計によるものです。ステータスモデルのデザインパターン

ステータスがあるモデルがあります。モデルのインスタンスは複数あり、定義済みのステータスはわずかです(作成、更新、取得など)。個々のステータスごとに、モデルの計算ロジックがいくつかあります。例えば。 model.cost()は、ステータスごとに異なって計算されます。

モデルを保存するときにActiveRecordが自動的に正しいmodel_status_idを設定したいと思っています。

model.status = StatusModel.retrieved 

と私は、このデータベースにモデルの行の状態を保存する必要があり

case status 
    when renewed 
    # ... 
    when retrieved 
    # .. 
end 

思考は、私が今持っているものです:私はこのような何かを行うことが理想的な状況で考えます:

ModelStatus < ActiveRecord::Base 
    has_many :models 
Model < ActiveRecord::Base 
    belongs_to :model_status 

しかし、これは私にコードで多くの問題を与えています。誰かがこのために良いアイデアやパターンを持っていますか?

+0

ステータスが事前定義されている場合は、DBではなくコードの定数として保存するだけでは不十分ですか? – Olly

答えて

1

なぜ実際のモデルのステータス部分を保持しないのですか?彼らは事前に定義されている場合、それはあまりにも多くの仕事ではありません。

class Model < ActiveRecord::Base 

    STAT_CREATED = 1 
    STAT_RENEWED = 2 
    STAT_RETRIEVED = 4 

    validates_inclusion_of :status, 
         :in => [1, 2, 4] 


    def created? 
    status & STAT_CREATED 
    end 

    def renewed? 
    status & STAT_RENEWED 
    end 

    def retrieved? 
    status & STAT_RETRIEVED 
    end 

end 

この方法で、あなたは(?model.created @場合など)を直接モデルインスタンスをテストするか、そのようなあなたのcase文書くことができ、次のいずれか

case @model.status 
when Model::STAT_CREATED 
... 
when Model::STAT_RENEWED 
... 
+0

ありがとう!かなり論理的に見えます。時には複雑すぎると思うこともあります。 – benvds

1

acts_as_state_machineプラグインもご覧ください。私は最近、プロジェクトでそれを使用し、それはうまくいった。

2

あなたが説明しているのは、状態マシンの場合のようです。

多くのRubyステートマシンの実装があります。あなたは、ステートマシンを定義するときは、いくつかの米国遷移を定義することができますruby-toolbox

でかなり代表的なリストを見ることができます。各は、モデルを1つの状態から別の状態に移行して途中でコードを実行します。そのためのDSLは、通常かなりいいです。

あなたの例では、

model.retrieve! 

のようになります。これは、それがにしたものは何でもからモードの状態を変更しますがを検索したり、現在のステータスがに遷移しない場合に例外をスローを取得しました。

関連する問題