# AASM is a continuation of the acts-as-state-machine rails plugin, built for plain Ruby objects. gem 'aasm', '~> 4.12', '>= 4.12.0'
instance method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
## # check status ##
job.running? # => true job.may_run? # => false
job.aasm.current_state # stage3 job.aasm_state # => 'sleeping' job.aasm.human_state # => 'sleeping' job.aasm.states(:permitted => true).map(&:name) # show all permitted states (from initial state) job.aasm.states(:permitted => false).map(&:name) # show all non permitted states job.aasm.events.map(&:name) # show all possible (triggerable) events from the current state
## # change status 的方法要根據在 AASM 中 event 所定義的名稱 ## job.sleep # => triggered :sleep job.sleep! # => triggered :sleep!
# ./OnePageShop/app/models/order.rb class Order < ApplicationRecord # Concerns macros include AASM
# Attributes related macros aasm column: 'status', no_direct_assignment: true, requires_lock: true do # 等待付款 state :waiting_for_payment, initial: true # 已付款 state :paid # 已出貨 state :shipped # 訂單逾期 state :expired # 已退款 state :refunded
after_all_transitions :generate_status_transition_log!
event :mark_as_paid do transitions from: %i(placed waiting_for_payment), to: :paid end
event :mark_as_shipped do transitions from: :paid, to: :shipped end
event :mark_as_expired do transitions from: :waiting_for_payment, to: :expired end
event :mark_as_refunded do transitions from: :paid, to: :refunded 大专栏 [Gem] AASM 狀態機n class="keyword">end end
# ...
private # callback methods def can_not_be_destroyed throw :abort end
def generate_status_transition_log! status_logs.create!(status: aasm.to_state) end end
# ./OnePageShop/app/models/transaction.rb class Transaction < ApplicationRecord # Concerns macros include AASM
# Attributes related macros aasm column: 'status', no_direct_assignment: true, requires_lock: true do # 等待繳款 state :waiting_for_payment, initial: true # 已付款 state :paid # 交易失敗 state :failed # 取消 state :canceled # 逾期 state :expired # 已退款 state :refunded
after_all_transitions :generate_status_transition_log!
event :mark_as_paid do transitions from: :waiting_for_payment, to: :paid end
event :mark_as_paid do transitions from: :waiting_for_payment, to: :failed end
event :mark_as_canceled do transitions from: :waiting_for_payment, to: :canceled end
event :mark_as_expired do transitions from: :waiting_for_payment, to: :expired end
event :mark_as_refunded, after: :check_all_transactions_refunded! do transitions from: :paid, to: :refunded end end
# callbacks after_initialize :generate_trade_number after_create :generate_status_change_log! after_update :update_order_status!
private # callback methods def generate_status_change_log! status_logs.create!(status: aasm.current_state) end
def generate_status_transition_log! status_logs.create!(status: aasm.to_state) end
def update_order_status! return if payment_info.nil?
if self.paid? # set all waiting for payment transaction as canceled self.order.transactions.waiting_for_payment.each do |transaction| transaction.mark_as_canceled! if transaction.may_mark_as_canceled? end
self.order.mark_as_paid! if self.order.may_mark_as_paid? end end
def check_all_transactions_refunded! # 若沒有其餘等待付款或已付款的交易,則將訂單狀態改為已退款 if !Transaction.where(order_id: self.order_id, status: %i(waiting_for_payment paid)).exists? self.order.mark_as_refunded! end end end