2009-08-25 7 views
3

모델 상태를 구현하는 데 문제가 있습니다. 이는 잘못된 설계 때문일 수 있습니다.상태 모델 디자인 패턴

상태가있는 모델이 있습니다. 모델의 인스턴스가 여러 개있을 수 있으며 사전 정의 된 상태 (예 : created, renewed, retrieved 등)가있을 수 있습니다. 각 개별 상태에 대해 모델에 대한 계산 논리가 있습니다. 예 : 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 @model.status 
when Model::STAT_CREATED 
... 
when Model::STAT_RENEWED 
... 
+0

고마워요! 꽤 논리적 인 것처럼 보입니다. 때때로 나는 너무 복잡하다고 생각합니다. – benvds

1

또한 acts_as_state_machine 플러그인을 살펴보십시오. 나는 최근에 그것을 프로젝트에 사용했고 잘 작동했다.

2

당신이 묘사 한 것은 상태 기계의 완벽한 경우 인 것처럼 보입니다.

많은 Ruby 상태 머신 구현이 있습니다. 상태 머신 여러 미국전환 정의 할 수 있습니다를 정의 할 때 당신은 ruby-toolbox

에서 공정하게 대표 목록을 볼 수 있습니다. 각 은 모델을 하나의 상태에서 다른 상태로 전환하여 길을 따라 일부 코드를 실행합니다. DSL은 대개 꽤 좋습니다.

귀하의 예는 현재 상태 검색 로 전환하지 않을 경우 예외 모드가 이었다 어떤에서 상태를 검색을 변경하거나 던질 것이다

model.retrieve! 

이 같을 것이다.