我正在为Rails 3 / Active Record项目寻找一个相对简单的状态机插件。
我做了一些研究并提出了以下插件:
但它们看起来非常相似,所以我很想知道是否有人对其中任何人有过实际经验。
谢谢!
答案 0 :(得分:12)
state_machine似乎是人们说要使用的人,至少是我与之交谈过的人。它与环境无关,因此您不必在应用程序的某个部分使用一个状态机,而在应用程序的另一部分使用完全不同的状态机。
2015年2月更新
不幸的是,状态机不再维护,并且存在许多问题,这使得它成为不太有利的选择。但是,该项目的this fork得到了积极维护并且看起来很稳定。答案 1 :(得分:4)
我最终使用了stateflow并且喜欢它。 https://github.com/ryanza/stateflow
它使用rails 3.0运行,它与几个rails 3.0测试版中的状态机代码的方法类似,但从最终版本中删除。我没有跟着看当前关于在rails中使用状态机的想法 - 但我想如果状态机在将来的版本中重新集成,它将有点像这样。如果我想放弃gem并使用核心功能
,希望这意味着最小的代码更改答案 2 :(得分:3)
我会小心翼翼地接近Transitions。作者/提取者说他没有时间维护它,并且通常赞成state_machine他的新项目。
另一方面,它确实有效(虽然检查未解决的问题,看看它是否适用于您的情况)。我自己在项目中使用Transitions,但是对于一个简单的状态机。
我之前在Rails 2项目中使用过act作为状态机,它确实很好(即使是非常复杂的状态机)
答案 3 :(得分:2)
SimpleStateMachine是一个简单的DSL,用于装饰状态转换保护的现有方法。
class LampSwitch
extend SimpleStateMachine
def initialize
self.state = 'off'
end
event :push_switch, :off => :on
end
lamp = LampSwitch.new
lamp.state # => 'off'
lamp.off? # => true
lamp.push_switch #
lamp.state # => 'on'
lamp.on? # => true
它与ActiveModel验证一起使用,并允许使用参数调用事件:
class User < ActiveRecord::Base
...
def activate_account(activation_code)
if activation_code_invalid?(activation_code)
errors.add(:activation_code, 'Invalid')
end
end
event :activate_account, :invited => :activated
end
user = User.new
user.activate_account!('INVALID') # => raises ActiveRecord::RecordInvalid
user.activated? # => false
user.activate_account!('VALID')
user.activated? # => true
它可以拯救异常:
def download_data
raise Service::ConnectionError
end
event :download_data, Service::ConnectionError => :download_failed
user.download_data # catches Service::ConnectionError
user.state # => "download_failed"
user.state_machine.raised_error # the raised error
答案 4 :(得分:0)
即使是最简单的状态机宝石也有比我需要的功能更多的功能,所以我决定推出自己的解决方案。我尝试过Transitions和Stateflow,但两者都有小问题。
答案 5 :(得分:0)
我建议使用Workflow,因为我觉得它是所有状态机中最简单的。