我在实现模型的状态时遇到了问题。这可能是由于错误的设计造成的。
有一个具有状态的模型。模型可以有多个实例,但只有几个预定义的状态(如:已创建、已续订、已检索等)。对于每个单独的状态,模型都有一些计算逻辑。例如,对于每种状态,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然而,这给我的代码带来了很多问题。有没有人对此有好的想法或模式?
发布于 2009-08-25 10:07:23
为什么不保留实际模型的状态部分呢?如果它们是预定义的,那就不需要太多的工作:
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
...发布于 2009-08-25 16:53:55
您所描述的似乎是状态机的完美案例。
有许多Ruby状态机实现。你可以在ruby-toolbox上看到一个相当有代表性的列表
在定义状态机时,您可以定义多个状态和转换。每个转换,将模型从一种状态转换到另一种状态,并在此过程中执行一些代码。它的DSL通常是相当不错的。
您的示例将如下所示
model.retrieve!这会将模式状态从原来的状态更改为retrieved,或者如果当前状态未转换为retrieved,则会抛出异常。
发布于 2009-08-25 16:44:43
也可以试着看看acts_as_state_machine插件。我最近在一个项目中使用了它,它工作得很好。
https://stackoverflow.com/questions/1327138
复制相似问题