gpt4 book ai didi

ruby-on-rails - 使用 pluginaweek 的 state_machine,我可以在事件期间引用 activerecord 对象吗?

转载 作者:行者123 更新时间:2023-12-04 06:07:32 25 4
gpt4 key购买 nike

我正在尝试实现将对象转换为 :suspended 状态的“挂起”事件。但我需要能够“取消暂停”,并返回到之前的状态。我在模型中添加了一个 previous_state 字段,但我看不到如何在事件 block 中访问它。

这是我试图实现的基本逻辑:

event :suspend do
owner.previous_state = self.state
transition [:new, :old] => :suspended
end

event :unsuspend do
transition :suspended => owner.previous_state.to_sym
owner.previous_state = nil
end

state_machine 文档不是很有帮助,我在网上找不到示例。有时很难知道如何向谷歌描述一些东西:)

最佳答案

state_machine 的作者在这里也提供了一个替代方案:https://groups.google.com/d/msg/pluginaweek-talk/LL9VJdL_x9c/vP1qv6br734J

以机智:

另一种可能的解决方案是对状态机的工作方式有一点创造性。 ORM 中有很多钩子(Hook),例如 ActiveRecord,它们使我们能够在流程的任何阶段设置状态。考虑以下:

class Vehicle < ActiveRecord::Base
before_validation do |vehicle|
# Set the actual value based on the previous state if we've just restored
vehicle.state = vehicle.previous_state if vehicle.restored?
end

state_machine :initial => :parked do
event :ignite do
transition :parked => :idling
end

event :restore do
transition any => :restored
end

state :parked do
validates_presence_of :name
end
end

# Look up previous state here...
def previous_state
'parked'
end
end

在这个例子中,一个新的状态,restored,被引入了,尽管它实际上并没有被持久化到数据库中。相反,我们提供了一个 before_validation Hook ,它根据先前的状态重写状态。你可以看到下面的结果:
v = Vehicle.new(:name => 'test')  # => #<Vehicle id: nil, name: "test", state: "parked">
v.save # => true
v.name = nil # => nil
v.ignite # => true
v # => #<Vehicle id: 1, name: nil, state: "idling">
v.restore # => false
v.errors # => #<OrderedHash {:name=>["can't be blank"]}>
v.state # => "idling"
v.name = 'test' # => "test"
v.restore # => true
v # => #<Vehicle id: 1, name: "test", state: "parked">
v.parked? # => true

这应该需要更少的数据库命中,因为它发生在验证之前。在我的情况下,完整的图片如下所示:
module Interpreting::Status

extend ActiveSupport::Concern

included do

before_validation :restore_previous_state, if: :interpreter_cancelled?

state_machine :state, :initial => :ordered do

before_transition :to => :interpreter_booked, :do => :set_previous_state

state :ordered

state :confirmed

state :interpreter_booked

state :interpreter_cancelled # Transient status
end

end


protected

def set_previous_state
self.previous_state = self.state
end

def restore_previous_state
self.state = self.previous_state
end

end

关于ruby-on-rails - 使用 pluginaweek 的 state_machine,我可以在事件期间引用 activerecord 对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5807374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com