mcpField
A
aasm-coder

aasm-coder

github.com/majesticlabs-dev开发5064 次安装7 周前更新
代码仓库

关于 aasm-coder

aasm-coder 面向 Rails 开发者,介绍如何用 AASM 管理工作流状态,涵盖条件转换、回调、错误处理和测试。

主要功能

  1. 01AASM 状态机模式
  2. 02条件与多重状态转换
  3. 03状态和事件回调
  4. 04安全及异常错误处理
  5. 05RSpec 状态机测试

适用场景

  1. 01建模 Rails 订单生命周期
  2. 02为工作流转换添加条件
  3. 03在状态变化时运行回调
  4. 04使用 RSpec 测试状态机

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/majesticlabs-dev/majestic-marketplace --skill aasm-coder

安装后在 Claude Code 中输入/aasm-coder确认已加载。

详细介绍

AASM 编码器

用于在 Rails 中管理工作流状态的状态机模式。

设置

# Gemfile
gem "aasm", "~> 5.5"

基本状态机

class Order < ApplicationRecord
  include AASM

  aasm column: :status do
    state :pending, initial: true
    state :paid
    state :processing
    state :shipped
    state :cancelled

    event :pay do
      transitions from: :pending, to: :paid

      after do
        OrderMailer.payment_received(self).deliver_later
      end
    end

    event :process do
      transitions from: :paid, to: :processing
    end

    event :ship do
      transitions from: :processing, to: :shipped
    end

    event :cancel do
      transitions from: [:pending, :paid], to: :cancelled

      before do
        refund_payment if paid?
      end
    end
  end
end

用法

order = Order.create!
order.pending?      # => true
order.may_pay?      # => true
order.pay!          # Transition + callbacks
order.paid?         # => true

order.may_ship?     # => false (must process first)
order.aasm.events   # => [:process, :cancel]

# Scopes created automatically
Order.pending
Order.paid.where(user: current_user)

守卫条件

event :pay do
  transitions from: :pending, to: :paid, guard: :payment_valid?
end

def payment_valid?
  payment_method.present? && total > 0
end

# Usage
order.pay!  # Raises AASM::InvalidTransition if guard fails
order.pay   # Returns false (no exception)

回调

aasm do
  # State callbacks
  state :paid, before_enter: :validate_payment,
               after_enter: :send_receipt

  # Event callbacks
  event :ship do
    before do
      generate_tracking_number
    end

    after do
      notify_customer
    end

    transitions from: :processing, to: :shipped
  end
end

回调顺序:

  1. before(事件)
  2. before_exit(旧状态)
  3. before_enter(新状态)
  4. 持久化状态变更
  5. after_exit(旧状态)
  6. after_enter(新状态)
  7. after(事件)

多个转换

event :approve do
  transitions from: :pending, to: :approved, guard: :auto_approvable?
  transitions from: :pending, to: :review, guard: :needs_review?
  transitions from: :pending, to: :rejected  # fallback
end

第一个匹配的守卫条件优先。

错误处理

# Safe (returns false on failure)
order.pay  # => false if invalid

# Raises exception
begin
  order.pay!
rescue AASM::InvalidTransition => e
  Rails.logger.error("Invalid transition: #{e.message}")
end

# Check before transition
if order.may_pay?
  order.pay!
end

测试状态机

RSpec.describe Order do
  let(:order) { create(:order) }

  it "starts in pending state" do
    expect(order).to be_pending
  end

  describe "pay event" do
    it "transitions to paid" do
      expect { order.pay! }
        .to change(order, :status).from("pending").to("paid")
    end

    it "sends payment received email" do
      expect(OrderMailer).to receive_message_chain(:payment_received, :deliver_later)
      order.pay!
    end
  end

  describe "ship event" do
    context "when pending" do
      it "raises error" do
        expect { order.ship! }.to raise_error(AASM::InvalidTransition)
      end
    end

    context "when processing" do
      before { order.update!(status: :processing) }

      it "transitions to shipped" do
        expect { order.ship! }
          .to change(order, :status).to("shipped")
      end
    end
  end
end

高级模式

有关多个状态机、持久化选项和历史记录,请参阅:

  • references/aasm-patterns.md

相关技能

  • event-sourcing-coder - 当状态转换需要触发通知、webhook 或审计跟踪时,用于记录领域事件。

评论

支持 Markdown