State_machine以前的状态

时间:2013-09-12 11:42:22

标签: ruby-on-rails ruby state-machine

我正在使用rails state_machine gem。我有一个带有状态字段的模型Lead。我可以使用state_machine将状态更改为更改状态吗?我有一个联系人复选框,当用户点击它时,它将是lead.made_contact!但是当它们未经检查时,它应该被还原。 state_machine会帮忙吗?感谢。

2 个答案:

答案 0 :(得分:1)

您必须明确定义步骤:

event :next do
  transition from: :without_contact, to: :with_contact
end

event :back do
  transition from: :with_contact, to: :without_contact
end

这样您就可以.next.previous

状态机的强大之处在于你必须让对象自己处理。 你要仔细考虑授权和非法转换,然后你只需要使用事件。

具有非常明确的转换名称通常是非抽象状态机的标志。 (看看狂欢,基本上使用一个事件:next,抽象是完全的)

答案 1 :(得分:1)

如果您正在使用复选框建模交互,那么在我看来,您可以期待的唯一转换就是切换它。然后,状态消息可以是由此状态机的值确定的虚拟属性。

对于这种情况,状态机可能有点过分,但假设你为了问题而简化问题,这是另一种方法。

class Lead
  state_machine :contact_state, :initial => :unchecked, :namespace => "contact" do
    event :toggle do
      transition :unchecked => :checked, :unless => lambda {|obj| obj.contact_state }
      transition :checked => :unchecked, :if => lambda {|obj| obj.contact_state }
    end

    state :checked, :value => true
    state :unchecked, :value => false
  end

  def status
    contact_state ? "lead.made_contact!" : ""
  end
end

该代码产生以下行为。当然,您可以根据自己的喜好更改命名空间或属性。

irb(main):001:0> lead = Lead.new
=> #<Lead:0x007fccec42c898 @contact_state=false>
irb(main):002:0> lead.contact_state
=> false
irb(main):003:0> lead.status
=> ""
irb(main):004:0> lead.toggle_contact
=> true
irb(main):005:0> lead.contact_state
=> true
irb(main):006:0> lead.status
=> "lead.made_contact!"
irb(main):007:0> lead.toggle_contact
=> true
irb(main):008:0> lead.status
=> ""