【问题标题】:Persisting the state column on transition using rubyist-aasm (acts as state machine)使用 ruby​​ist-aasm 持久化状态列(充当状态机)
【发布时间】:2009-03-25 18:42:03
【问题描述】:

在使用 aasm 进行转换时将对象的状态保存到数据库的最佳方法是什么?我原以为这会自动发生,但事实并非如此。

(编辑:当我手动保存对象时,状态列会更新。但不会在转换时保存。)

我找不到这个插件有用的文档,所以如果你有更好的文档替代有限状态机实现的建议,那也可能会有所帮助。

【问题讨论】:

    标签: ruby-on-rails aasm acts-as-state-machine


    【解决方案1】:

    如果调用bang!形式的transition事件方法,状态会持续存在。例如,假设您有一个带有以下事件的对象:

    class Book < ActiveRecord::Base
      # ... 
    
      aasm_event :close do
        transitions :to => :closed, :from => [:opened]
      end
    
      # ...
    end
    

    调用book.close 会将状态设置为closed,但不会自动保存。调用 book.close! 将设置状态*并*自动保存 AR 对象。

    【讨论】:

      【解决方案2】:

      正如 Colin 所建议的,AASM 将为您保留您的更改。 Markus 所说的完全不正确,只是最新版本的 gem 有一个错误。

      在 lib/persistence/active_record_persistence.rb 的第 180 行(您可以通过运行 gem:unpack 获得此信息),您应该会看到以下注释:

      将状态写入状态列并将其持久化到数据库 使用 update_attribute(绕过验证)

      然而,在代码中,它实际上调用了 save!

      unless self.save
      

      当底层模型验证失败时会出现该错误,因为默认情况下保存方法不会绕过验证。一个快速的解决方法是这样做:

      unless self.save(false)
      

      现在,转换确实将新状态保存到数据库中。

      【讨论】:

        【解决方案3】:

        我相信 AASM 会在转换后保持对象的状态。请参阅 aasm/lib/persistence/active_record_persistence.rb 中的第 180-189 行

        【讨论】:

          【解决方案4】:

          如果这是你想要的效果,我认为你必须在过渡中保存。根据设计,ActiveRecord(aasm 位于其之上)不会自动保存记录。

          如果您愿意,您可以在 callback 中进行保存(听起来很像)。

          【讨论】:

          • 这是不必要的。所有事件转换都有一个 bang 方法,它会自动保存记录。有关更多信息,请参阅我的答案。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-08-06
          • 1970-01-01
          • 2011-01-09
          • 2021-05-20
          • 1970-01-01
          • 2022-11-07
          • 1970-01-01
          相关资源
          最近更新 更多