aasm-coder
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAASM Coder
AASM 状态机实现
State machine patterns for managing workflow states in Rails.
在Rails中管理工作流状态的状态机模式。
Setup
环境搭建
ruby
undefinedruby
undefinedGemfile
Gemfile
gem "aasm", "~> 5.5"
undefinedgem "aasm", "~> 5.5"
undefinedBasic State Machine
基础状态机
ruby
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
endruby
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
endUsage
使用方法
ruby
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]ruby
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
Scopes created automatically
Order.pending
Order.paid.where(user: current_user)
undefinedOrder.pending
Order.paid.where(user: current_user)
undefinedGuards
守卫机制
ruby
event :pay do
transitions from: :pending, to: :paid, guard: :payment_valid?
end
def payment_valid?
payment_method.present? && total > 0
endruby
event :pay do
transitions from: :pending, to: :paid, guard: :payment_valid?
end
def payment_valid?
payment_method.present? && total > 0
endUsage
Usage
order.pay! # Raises AASM::InvalidTransition if guard fails
order.pay # Returns false (no exception)
undefinedorder.pay! # Raises AASM::InvalidTransition if guard fails
order.pay # Returns false (no exception)
undefinedCallbacks
回调函数
ruby
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
endCallback order:
- (event)
before - (old state)
before_exit - (new state)
before_enter - State change persisted
- (old state)
after_exit - (new state)
after_enter - (event)
after
ruby
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
Multiple Transitions
多分支转换
ruby
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
endFirst matching guard wins.
ruby
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第一个匹配的守卫规则生效。
Error Handling
错误处理
ruby
undefinedruby
undefinedSafe (returns false on failure)
Safe (returns false on failure)
order.pay # => false if invalid
order.pay # => false if invalid
Raises exception
Raises exception
begin
order.pay!
rescue AASM::InvalidTransition => e
Rails.logger.error("Invalid transition: #{e.message}")
end
begin
order.pay!
rescue AASM::InvalidTransition => e
Rails.logger.error("Invalid transition: #{e.message}")
end
Check before transition
Check before transition
if order.may_pay?
order.pay!
end
undefinedif order.may_pay?
order.pay!
end
undefinedTesting State Machines
状态机测试
ruby
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
endruby
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
endAdvanced Patterns
进阶模式
For multiple state machines, persistence options, and history tracking see:
references/aasm-patterns.md
关于多状态机、持久化选项以及历史追踪的内容,请查看:
references/aasm-patterns.md
Related Skills
相关技能
- - For recording domain events when state transitions should trigger notifications, webhooks, or audit trails.
event-sourcing-coder
- - 用于在状态转换需要触发通知、Webhook或审计追踪时记录领域事件。
event-sourcing-coder