以下是系统规格:=
- 语言 红宝石
- 框架帕德里诺
- ORM Mongoid
- 数据库 MongoDB
现在我有一个 Person 模型,它有两个分别维护状态的字段。
class Person
include Mongoid::Document
include Mongoid::Timestamps
# Field Names
#-----------------
field :name, :type => String
field :sms_state, :type => String, :default => 'main_menu'
field :ivr_state, :type => String, :default => 'main_menu'
end
我使用 Monkey Patching 添加状态机,因为我需要根据请求控制器更新状态。即,如果请求 SMS 控制器,则只有 sms_state 的 SMS 状态机应该 Monkey Patched 并且类似地对于 IVR 控制器我这样做 Monkey Patching,(Monkey PAtching 的原因是除了状态字段之外,状态机的整个流程和状态都是相同的,和事件变化...)
Person.class_eval do
state_machine :state_field, :initial => :main_menu do
# State Machine Flow
# Events Details
#===============================================================
event :state_reset do
transition all - [:country_confirmation, :topup_confirmation] => :main_menu
end
event :country_list do
transition [:main_menu, :did_purchased, :country_probed] => :country_listed
end
# States Details
#===============================================================================
state :main_menu do
define_method (:get_msg) {|obj| current_module.get_main_menu_msg(obj.dids.count, obj.spokn_id) }
end
state :country_listed do
define_method (:get_msg) {|obj| current_module.get_country_list_msg Country.all }
end
end
end
但它仅适用于状态机。假设它对 SMS 控制器工作正常,如果请求来自 IVR 控制器,则 Ivr 状态机是 Monkey Patched。但是状态字段没有,我得到以下错误
StateMachine::InvalidTransition - Cannot transition sms_state via :ivr_country_list from :country_listed