AASM 的基本狀態

通常,你最終會建立包含狀態的模型,並且該狀態將在物件的生命週期內發生變化。

AASM 是一個有限狀態機啟用程式庫,可以幫助你輕鬆完成物件的流程設計。

在你的模型中有這樣的東西與 Fat Model,Skinny Controller 的想法完全一致,這是 Rails 最佳實踐之一。該模型唯一負責管理其狀態,其變化以及生成由這些變化觸發的事件。

要在 Gemfile 中安裝

gem 'aasm'

考慮一個應用程式,其中使用者引用產品的價格。

class Quote

  include AASM

  aasm do
    state :requested, initial: true  # User sees a product and requests a quote
    state :priced                    # Seller sets the price 
    state :payed                     # Buyer pays the price
    state :canceled                  # The buyer is not willing to pay the price
    state :completed                 # The product has been delivered.

    event :price do
        transitions from: requested, to: :priced
    end

    event :pay do
        transitions from: :priced, to: :payed, success: :set_payment_date
    end

    event :complete do
        transitions from: :payed, to: :completed, guard: product_delivered?
    end

    event :cancel do
        transitions from: [:requested, :priced], to: :canceled
        transitions from: :payed, to: canceled, success: :reverse_charges
    end

   
  end

  private

  def set_payment_date
    update payed_at: Time.zone.now
  end
end

Quote 類的狀態可以去,但它最適合你的過程。

你可以將狀態視為過去,如前面的示例或其他時態的演算法,例如:定價,支付,交付等。狀態的命名取決於你。從個人角度來看,過去的狀態更好地工作,因為你的最終狀態肯定會是過去的行為並且更好地與事件名稱聯絡起來,這將在後面解釋。

注意: 注意你使用的名稱,你必須擔心不使用 Ruby 或 Ruby on Rails 保留的關鍵字,如 validendbeing 等。

定義了狀態和轉換後,我們現在可以訪問 AASM 建立的一些方法。

例如:

Quote.priced  # Shows all Quotes with priced events
quote.priced? # Indicates if that specific quote has been priced
quote.price!  # Triggers the event the would transition from requested to priced.

正如你所看到的,事件具有轉換,此轉換決定了狀態在事件呼叫時的更改方式。如果事件由於當前狀態而無效,則將引發錯誤。

例如,事件和轉換還有一些其他回撥

guard: product_delivered?

將呼叫將返回布林值的 product_delivered? 方法。如果結果為 false,則不會應用轉換,如果沒有其他轉換可用,則狀態不會更改。

success: :reverse_charges

如果該翻譯成功發生,則將呼叫:reverse_charges 方法。

AASM 中還有其他幾種方法,在此過程中有更多回撥,但這將幫助你建立具有有限狀態的第一個模型。