5

问题是,状态机是否总是静态定义(在类上)?或者有没有办法让我拥有它,所以类的每个实例都有它自己的一组状态?

我正在检查Stonepath以实现任务引擎。我并没有真正看到“状态”和“任务”之间的区别,所以我想我可以直接将一个任务映射到一个状态。这将使我能够动态定义任务列表(或工作流),而无需执行以下操作:

aasm_event :evaluate do
  transitions :to => :in_evaluation, :from => :pending
end

aasm_event :accept do
  transitions :to => :accepted, :from => :pending
end

aasm_event :reject do
  transitions :to => :rejected, :from => :pending
end

相反,一个 WorkItem(主要的工作流/任务管理器模型)只会有很多任务。然后任务会像状态一样工作,所以我可以做这样的事情:

aasm_initial_state :initial

tasks.each do |task|
  aasm_state task.name.to_sym
end

previous_state = nil
tasks.each do |tasks|
  aasm_event task.name.to_sym do
    transitions :to => "#{task.name}_phase".to_sym, :from => previous_state ? "#{task.name}_phase" : "initial"
  end
  previous_state = state
end

但是,我不能用aasm gem做到这一点,因为这些方法 (aasm_stateaasm_event) 是类方法,因此具有该状态机的类的每个实例都具有相同的状态。我想要它,所以“WorkItem”或“TaskList”会根据它所拥有的任务动态地创建一系列状态和转换。

这将允许我动态定义工作流,并且只需将状态映射到任务。

状态机曾经这样使用过吗?似乎这个ruby​​ 工作流 gem与我所描述的相似。

更新:我可以看到做类似以下的事情,但它似乎有点骇人听闻:

@implementation_state_machine = Class::new do
  include AASM
  aasm_initial_state :initial

  tasks.each { |state| aasm_state :"#{task.name}"}
  # ...
end

...我的模型上的属性将在哪里implementation_state_machine。我必须重写method_missing以将与状态相关的方法 ( accepted_phase?) 委托给实现匿名类。

4

2 回答 2

1

是的,这确实看起来很hacky而且很混乱。我最近写了一个新的 gem,它允许您使用带有决策设置的动态“to”转换。

因此,与其动态构建事件和转换,是否可以先将它们映射出来,然后使用决定设置让转换决定进入哪个新状态?您还可以将您的 from 转换包装在一个数组中,这样您就不需要这样做 :from => previous_state ?"#{task.name}_phase" : "initial",你可以这样做 :from => [ :cool_task_phase, :initial ]

我发现首先设置你的转换和事件,可以让你更好地了解你的模型正在做什么。

http://github.com/ryanza/stateflow 查看

希望你能从中找到一些用处。

于 2010-03-31T07:38:07.377 回答
1

在我的实现状态机是一个哈希https://github.com/mpapis/state_attr

state_attr :state, {
  nil => :first,
  :first => [:second, :third],
  :second => :last,
  :third => nil,
}

您可以定义任意数量的状态属性

顺便说一句:在后台仍然有一个类,但只是作为属性的代理

于 2011-05-17T00:53:00.920 回答