ruby有一个act as state machine的插件,可以实现工作流或者多步骤向导的功能。
state machine,是计算机科学里面一种模型,这个插件主要实现的是finite state machine,既有限状态自动机。
首先,AASM的安装:
安装好之后需要在你的Model里面加入
下面是一个简单的例子。来介绍AASM的使用。
加入我们有一个person的model,一个person可以处于三种状态,sleeping, working 还有eating.
初始状态是sleeping,
从sleeping只可以通过eat事件,转到eating,不可以转到working.(吃了饭才能工作)。
从working只可以通过eat事件,转到eating,不可以转到sleeping. (不能空肚子睡觉)。
然后从eating可以通过work事件转到working,或者sleep转到sleeping.
这些可以转化成下面的代码
include AASM
aasm_column :current_state #定义那个字段来储存当前状态
aasm_initial_state :sleeping #定义初始状态
#定义三个不同的状态
aasm_state :sleeping
aasm_state :eating
aasm_state :working
#定义每个event及event发生时引发的状态转换
aasm_event :eat do
transitions :from => [:sleeping,:working], :to => :eating
end
aasm_event :work do
transitions :from => :eating, :to =>:working
end
aasm_event :sleep do
transitions :from => :eating, :to => :sleeping
end
end
这样基本上就已经建好了state machine了。可以在console里面实验一下:
=> #<Person id: 10, name: nil, current_state: "sleeping", created_at: "2010-05-09 06:32:41", updated_at: "2010-05-09 06:32:41">
ruby-1.8.7-p249 > p.aasm_events_for_current_state
=> [:eat]
ruby-1.8.7-p249 > p.eat
=> true
ruby-1.8.7-p249 > p
=> #<Person id: 10, name: nil, current_state: "eating", created_at: "2010-05-09 06:32:41", updated_at: "2010-05-09 06:32:41">
ruby-1.8.7-p249 > p.aasm_events_for_current_state
=> [:sleep, :work]
ruby-1.8.7-p249 > p.work
=> true
ruby-1.8.7-p249 > p
=> #<Person id: 10, name: nil, current_state: "working", created_at: "2010-05-09 06:32:41", updated_at: "2010-05-09 06:32:41">
ruby-1.8.7-p249 > p.aasm_current_state
=> :working
可以看到,可以直接用 p.event的形式,来触发事件。
aasm_current_state来获得当前状态,aasm_events_for_current_state 来获得当前状态可用的event.
结合到view的时候也很简单。把aasm_events_for_current_state获得的集合交给用户选择。
返回到server之后的param经过验证之后。可以用p.send(param[:event])的形式触发。
这里的例子是一个工作流的例子。多步骤向导也很类似,这里不再赘述。
除此之外,AASM还提供了很多有用的callback, 感兴趣的朋友可以深入研究一下。
github列出了下面几个:
oldstate:exit*
event:before
__find transition, if possible__
transition:on_transition*
oldstate:before_exit
newstate:before_enter
newstate:enter*
__update state__
event:success*
oldstate:after_exit
newstate:after_enter
event:after
obj:aasm_event_fired*
{ 1 } Comments
嗨!感谢你介绍的这么详细还有示例,后来通过搜索也看到你在JavaEye里面写的文章了。第一时间就看到你写的这篇文章,只是最近才有时间开始研究。
通过学习例子,已经初步了解如何建立简单的流程。
只是在gem里已经安装AASM的情况下,Rails 3里面总是报错没有找到该gem,而且我也通过在项目夹下执行bundle install。
再继续研究下,感觉act as state machine还是挺有意思的 :)
Post a Comment