关于 aasm-coder
aasm-coder 面向 Rails 开发者,介绍如何用 AASM 管理工作流状态,涵盖条件转换、回调、错误处理和测试。
主要功能
- 01AASM 状态机模式
- 02条件与多重状态转换
- 03状态和事件回调
- 04安全及异常错误处理
- 05RSpec 状态机测试
适用场景
- 01建模 Rails 订单生命周期
- 02为工作流转换添加条件
- 03在状态变化时运行回调
- 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
回调顺序:
before(事件)before_exit(旧状态)before_enter(新状态)- 持久化状态变更
after_exit(旧状态)after_enter(新状态)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