はじめに
Railsアプリケーションにおいて、オブジェクトの状態管理は重要な課題の一つです。AASM (Acts As State Machine) gemは、複雑な状態遷移を効率的に管理します。本記事では、AASMの基本的な使い方を解説していきます。
使用方法
セットアップ
まず、Gemfile
に以下の行を追加し、bundle install
を実行します。
Gemfile
gem 'aasm'
基本的な使用方法
AASMを使用するには、モデルにinclude AASM
を追加し、状態とイベントを定義します。以下はOrder
モデルの例です。
app/models/order.rb
class Order < ApplicationRecord
include AASM
aasm column: 'state' do
state :pending, initial: true
state :processing, :shipped, :cancelled
event :process do
transitions from: :pending, to: :processing
end
event :ship do
transitions from: :processing, to: :shipped
end
event :cancel do
transitions from: [:pending, :processing], to: :cancelled
end
end
end
state
カラムを使用して状態を保存- 初期状態は
pending
process、ship
,cancel
イベントを定義
状態の遷移
状態を遷移させるには、定義したイベントメソッドを呼び出します。
order = Order.create # 初期状態は pending
order.process! # pending から processing へ
order.ship! # processing から shipped へ
状態の確認
現在の状態を確認するには、以下のようにします。
order.pending? # => true/false
order.processing? # => true/false
order.shipped? # => true/false
order.cancelled? # => true/false
遷移の条件
遷移に条件を追加することができます。
aasm do
event :ship do
transitions from: :processing, to: :shipped, guard: :all_items_in_stock?
end
end
def all_items_in_stock?
order_items.all? { |item| item.in_stock? }
end
この例では、all_items_in_stock?
メソッドがtrue
を返す場合のみship
イベントが実行されます。
コールバック
遷移の前後にコールバックを追加できます。
aasm do
event :ship do
before do
update_inventory
end
transitions from: :processing, to: :shipped
after do
send_shipping_notification
end
end
end
エラーハンドリング
遷移が失敗した場合、AASMは例外を発生させます。
begin
order.ship!
rescue AASM::InvalidTransition => e
puts "Cannot ship order: #{e.message}"
end
高度な使用例
より複雑なワークフローの例として、記事の公開プロセスを考えてみます。
app/models/article.rb
class Article < ApplicationRecord
include AASM
aasm column: 'status', whiny_transitions: false do
state :draft, initial: true
state :submitted, :reviewed, :approved, :published, :archived
event :submit do
transitions from: :draft, to: :submitted
end
event :review do
transitions from: :submitted, to: :reviewed
end
event :approve do
transitions from: :reviewed, to: :approved
end
event :publish do
transitions from: :approved, to: :published, guard: :publishable?
end
event :archive do
transitions from: [:published, :approved], to: :archived
end
end
def publishable?
!title.blank? && !content.blank?
end
end
- 記事は複数の状態(下書き、提出済み、レビュー済み、承認済み、公開済み、アーカイブ済み)を持つ
whiny_transitions: false
を設定して、無効な遷移時に例外を発生させないようにするpublishable?
メソッドを使用して、公開前にタイトルと内容が存在することを確認する
まとめ
AASMは、Railsアプリケーションにおける状態管理を大幅に簡素化し、コードの可読性と保守性を向上させる強力なツールです。状態遷移のロジックを明確に定義し、ビジネスルールを適切に実装することで、より堅牢で柔軟なアプリケーションの開発が可能になります。