1

我们有一个 Ruby on Rails 应用程序。

我们使用 Ruby 的 aasm gem 来管理对象的状态。

has_state
aasm do
    state :created, :initial => true
    state :submitted
    state :rejected
    state :approved

    event :submit do
        transitions :to => :submitted, :from => [:created]
    end

    event :mark_as_incomplete do
        transitions :to => :created, :from => [:submitted]
    end

    event :approve do
        transitions :to => :approved, :from => [:submitted]
    end

    event :reject do
        transitions :to => :rejected, :from => [:submitted]
    end
end

如果我们知道一个对象的当前状态,可以使用

object.aasm_current_state

而且我们也知道要转换到的状态,我们如何调用事件?

请注意,from-state 和 to-state 是变量,因此我们需要动态地执行上述操作。当然,对于某些 to-state 和 from-state 组合,转换不可用,在这种情况下,我们应该检测到错误。

我们还假设在任何两个状态组合(to-state 和 from-state)之间,只有 1 个事件,我认为理论上可以有超过 1 个。

我认为这可以通过深入研究 aasm 源代码的内部来实现,可以说这可能不是一个好习惯。有什么想法吗?

只是想知道以前是否有人这样做过。

谢谢!

4

2 回答 2

2

AASM 没有提供这样做的方法,但是您自己的答案已经足够接近您想去的地方了。AASM 建立在这样的假设之上,即状态机允许从一种状态到另一种状态的多种不同转换。

如果事件名称与您无关,您可以重用目标状态名称作为事件名称,如下所示:

aasm do
  ...
  event :approved do
    transitions :from => :submitted, :to => :approved
  end
  ...
end

这样,您只需知道目标状态名称即可触发事件

approval_request.send(to_state)

默认情况下,如果不允许此转换,AASM 会引发异常。如果您不喜欢该异常,请设置whiny_transitionsfalse,如下所示:

aasm :whiny_transitions => false do
   ...
end
于 2012-11-06T08:05:38.873 回答
0

这是我的代码。to_state 和 from_state 是从和到的状态。

ApprovalRequest.aasm_events.each do |event_key, event_obj|
    if event_obj.transitions_from_state?(from_state) &&
        event_obj.transitions_to_state?(to_state)
        self.approval_request.send "#{event_key.to_s}!"
    end
end

对此实施有何评论?

于 2012-11-05T18:05:59.483 回答