希望这不是一个愚蠢的问题,我只是没有忽略Ruby / Rails状态机(AASM,Transitions,AlterEgo等)中的某些东西。
据我所知,这些状态机实现的前言是事件将被触发,并且将根据旧状态和新状态触发该事件的适当转换。但是,它们似乎没有相反的方式;假设用户想要将状态从“已创建”更改为“已分配”并且发生正确的转换,而不是触发导致当前状态转换为新状态的事件。
基本上,我希望用户能够从可用状态的选择框中选择一个新状态,并执行相应的转换,警卫,成功回调等。
有谁知道现有的状态机实现是否支持这个?
答案 0 :(得分:2)
状态机本质上不允许您任意跳转到系统中的任何状态。每个都有一个入口点,每次你想改变状态时,都会评估一些条件(其中一个可能是输入事件),下一个状态是这些条件的结果。但是,您可以拥有一个状态机,其中从每个状态到另一个状态定义了转换。
class Ticket
acts_as_state_machine :initial => :new
state :new
state :open
state :resolved
event :open do
transitions :to => :open,
:from => [:new, :resolved], :guard => :can_be_open?
end
event :new do
transitions :to => :new,
:from => [:open, :resolved], :guard => :can_be_new?
end
event :resolved do
transitions :to => :resolved,
:from => [:open, :new], :guard => :can_be_resolved?
end
private
def can_be_resolved?
!resolution.blank?
end
...
end
@ticket = Ticket.create
@ticket.state # => new
@ticket.resolved!
@ticket.state # => resolved
因此,您需要从下拉列表中检查所需的状态,并因此调用正确的转换。您可以使用像attr_accessor :new_state
这样简单的内容,然后使用模型调用new_state => event
的{{1}}映射或case语句。
答案 1 :(得分:0)
你可以用我的gem flojo完成你想要做的事情。 只需在状态之后命名事件,并让这些事件触发从通配符状态到下拉列表中所选状态的转换。
如果您的下拉列表中有“待处理”状态,则可以使用以下代码段配置flojo事件
event :pending do
# :any is a wildcard state and is only valid as a begin state.
transition :any, :pending
end
提交表单后,您必须使用“wf_”前缀“pending”,将其转换为符号,然后将其发送到您的对象。在类中创建一个执行前缀和符号转换的方法会更简洁,然后委托发送。
your_object.send :wf_pending