zoukankan      html  css  js  c++  java
  • [Gem] AASM 狀態機

    @(Ruby on Rails)[rails, gem]

    1
    2
    3
    4


    # 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!

    class method

    1
    Job.aasm.states_for_select  # 產生可以直接套用到 select 的 options

    erb 中帶入 select options

    1
    <%= select_tag :transaction_state, options_for_select(Transaction.aasm.states_for_select), class: '-control' %>

    目錄

    [TOC]

    Automatic Scope

    在 AASM 中內建了 Model Scope 讓我們使用:

    1
    2
    # 假設 Order 有 paid 的狀態,那麼可以直接使用
    Order.paid

    i18n

    AASM 支援在 i18n 定義:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    zh-TW:
    activerecord:
    attributes:
    order:
    status/waiting_for_payment: 等待付款
    status/paid: 已付款
    status/failed: 已出貨
    status/canceled: 已逾期
    status/expired: 已退款
    status/refunded: 已退款

    使用範例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    # ./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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    # ./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

    參考

  • 相关阅读:
    Prototype的深度探索
    MySQL LIST分区
    CentOS6下Haproxy的安装配置
    haproxy做TCP层的负载均衡
    Shape Control for .NET
    如何通过 HSB 颜色模式构建夜间模式
    使用ICSharpCode.TextEditor制作一个语法高亮显示的XML编辑器
    Roslyn介绍
    信息安全名词
    用彩虹表破解MD5、LM Hash等复杂加密密码
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12099826.html
Copyright © 2011-2022 走看看