重构 使用 state_machine 有很多相似的 event 如何 DRY?

yesmeck · 发布于 2013年8月22日 · 最后由 yesmeck 回复于 2013年8月22日 · 1894 次阅读
865

大概代码是这样:

# app/models/concerns/member_state.rb
module MemberState
  extend ActiveSupport::Concern

  included do
    state_machine :member_state, initial: :initial, namespace: 'member' do
      event :event1 do
        transition :initial => :state1
      end

      event :event2 do
        transition :state1 => :state2
      end

      event :event3 do
        transition :state2 => :state3
      end

      ...
    end
  end
end

# app/models/concerns/admin_state.rb
module AdminState
  extend ActiveSupport::Concern

  included do
    state_machine :admin_state, initial: :initial, namespace: 'admin' do
      event :event1 do
        transition :initial => :state1
      end

      event :event2 do
        transition :state1 => :state2
      end

      event :event3 do
        transition :state2 => :state3
      end

      ...
    end
  end
end

# app/models/order.rb
class Order < ActiveRecord::Base
  include MemberState
  include AdminState

  ...
end

想要重用相同的 event 定义该如何做呢?

共收到 9 条回复
4514
event :event do
    transition :initial => :state1 , :state1 => :state2 , :state2 => :state3
end

这样通过一个event事件就可以控制三个状态的跳转了

4514

我是不是理解错了,你想实现的是多个模型的状态机事件公用嘛? 这个貌似无解,在api中没看到过

865

#2楼 @lionzixuanyuan 我是想相同的事件和相同的状态转换能不能不重復写

4514

#3楼 @yesmeck 那你可以考虑下是否可以这样:让你的MemberState和AdminState都继承自一个State的父类,然后在这个父类中定义状态机

865

可是这个两个状态的名字不一样呀

4514

#5楼 @yesmeck 状态的名字不一样应该没有影响的,只要一个状态机事件中不出现一个状态可以迁移到多个状态的情况就可以了啊

865

@lionzixuanyuan = =我愚钝还是不大懂,能否给个示例看看

4514

#7楼 @yesmeck

event :event do
    transition :initial => :state1 , :initial => :state2
end

上述的情况是错误的,因为通过这个事件,无法确认initial状态到底要迁移到哪个状态,所以上面的这个事件必须要拆成两个,然后根据情况分别调用。

event :event do
    transition :state1 => :initial ,  :state1 => :initial
end

这种情况是允许的,你自己体会一下,应该就会有思路了

865

好吧,是我给的示例代码有问题,member_state 和 admin_state 是两个不同的状态,我并不是想把三个事件合成一个事件,而是,在这两个状态里会有相同的事件和状态转变,我是想能不能不要重复定义。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册