在使用 aasm 进行转换时将对象的状态保存到数据库的最佳方法是什么?我原以为这会自动发生,但事实并非如此。
(编辑:当我手动保存对象时,状态列确实会更新。但是在转换时不会保存。)
对于这个插件,我找不到太多有用的文档,因此,如果您有关于具有更好文档的替代有限状态机实现的建议,那也可能会有所帮助。
在使用 aasm 进行转换时将对象的状态保存到数据库的最佳方法是什么?我原以为这会自动发生,但事实并非如此。
(编辑:当我手动保存对象时,状态列确实会更新。但是在转换时不会保存。)
对于这个插件,我找不到太多有用的文档,因此,如果您有关于具有更好文档的替代有限状态机实现的建议,那也可能会有所帮助。
如果你叫砰!转换事件方法的形式,状态将持续存在。例如,假设您有一个带有以下事件的对象:
class Book < ActiveRecord::Base
# ...
aasm_event :close do
transitions :to => :closed, :from => [:opened]
end
# ...
end
调用book.close
会将状态设置为closed
,但不会自动保存。调用book.close!
将设置状态*并*自动保存 AR 对象。
正如 Colin 所建议的,AASM 将为您保留您的更改。Markus 所说的完全不正确,除了最新版本的 gem 有一个错误。
在 lib/persistence/active_record_persistence.rb 的第 180 行(您可以通过运行 gem:unpack 获得此信息),您应该会看到注释,其中指出:
将状态写入状态列并使用 update_attribute 将其持久化到数据库(绕过验证)
但是,在代码中,它实际上调用了 save!
unless self.save
当底层模型验证失败时会出现该错误,因为默认情况下 save 方法不会绕过验证。一个快速的解决方法是这样做:
unless self.save(false)
现在,转换确实将新状态保存到数据库中。
我相信 AASM 会在转换后保持对象的状态。请参见 aasm/lib/persistence/active_record_persistence.rb 中的第 180-189 行
如果这是你想要的效果,我认为你必须在过渡中保存。根据设计,ActiveRecord(aasm 位于其之上)不会自动保存记录。
如果需要,您可以在回调中进行保存(听起来像您这样做)。