Ruby state machine gem
stateful_enumはここに載ってなかった
ohbarye.icon 眺めた感想
結論
ActiveRecord::Enumを使ったstate machineだけをサポートすればいいならstateful_enumが必要十分
ただし状態管理するcolumnの型はintegerに限る
他のORMやPOROでの状態遷移を扱いたかったらaasm
必要な機能は揃っている
状態遷移時のコールバックを記述できる
ActiveRecordのenumと連動した状態管理ができるのはstateful_enum, aasm 状態遷移が起きたイベントのクラスも作成し、遷移のたびにレコードをINSERTするstatesman
すべての変更履歴が残るのであとから追いやすい
他のgemでもコールバックに自前で書けば似たことはできるし、たいていのユースケースからすればtoo much
transitionsが選択肢から外れ、aasmでできることが増えた
その他にもいろいろ生まれてたが消えていった
aasm
ペースは落ちているが2022年も継続してリリースしてる
5.4.0 - October 07, 2022 (37KB)
5.3.1 - September 17, 2022 (101KB)
5.3.0 - July 22, 2022 (101KB)
5.2.0 - May 01, 2021 (99KB)
5.1.1 - August 11, 2020 (97KB)
https://gyazo.com/8a5d208542e8046211997bc8226b48c4
使い方
include AASMする
状態遷移と、状態遷移を起こすイベントを宣言的に定義する
code:ruby
class Job
include AASM
aasm do
state :sleeping, initial: true
state :running, :cleaning
event :run do
transitions from: :sleeping, to: :running
end
event :clean do
transitions from: :running, to: :cleaning
end
event :sleep do
end
end
end
状態遷移を起こさせるにはイベント名のメソッドを呼ぶ
ブロックを渡すと、状態遷移に成功した場合のみブロック内の処理が実行される
code:ruby
job = Job.new
job.run
job.run do
job.user.foo
end
状態遷移の中途でコールバックを書ける
ActiveRecordのenumと協調可
code:ruby
class Job < ActiveRecord::Base
include AASM
enum state: {
sleeping: 5,
running: 99
}
aasm column: :state, enum: true do
state :sleeping, initial: true
state :running
end
end
stateful_enum
リリースは少ない
0.7.0 - December 18, 2021 (12KB)
0.6.0 - June 06, 2019 (11.5KB)
0.5.0 - February 07, 2019 (11KB)
0.4.0 - December 28, 2016 (10.5KB)
0.3.1 - August 14, 2016 (10.5KB)
ohbarye.icon 提供する機能がシャープなので変更が少なくて済んでいるといえる
2022年にもコミットはある
https://gyazo.com/83638ba73ced64a0fc90dba35dcc70c9
他のgemは抽象化が過ぎる
enum columnはVARCHARでなくINTEGERに限る
非integerのカラムはサポートしてないので、string系の型のenumに使いたいのであれば候補から外れる
enumのkey名のメソッドはundefされるので注意
code:ruby
enum status: { active: 0, suspended: 1 }
# のような定義があるときに生えてくる obj.active! メソッドが消える
ohbarye.icon コードが少なく読みやすい。2~3ファイル読めばよいぐらい
statesman
2022年も継続してリリースしてる
10.0.0 - May 17, 2022 (44.5KB)
9.0.1 - February 04, 2022 (43KB)
9.0.0 - August 10, 2021 (43KB)
8.0.3 - June 08, 2021 (42.5KB)
8.0.2 - March 30, 2021 (41.5KB)
https://gyazo.com/196975a76d33ba87c6329e92638b782e
code:ruby
class OrderStateMachine
include Statesman::Machine
state :pending, initial: true
state :checking_out
state :purchased
state :shipped
state :cancelled
state :failed
state :refunded
transition from: :shipped, to: :refunded
guard_transition(to: :checking_out) do |order|
order.products_in_stock?
end
before_transition(from: :checking_out, to: :cancelled) do |order, transition|
order.reallocate_stock
end
before_transition(to: :purchased) do |order, transition|
PaymentService.new(order).submit
end
after_transition(to: :purchased) do |order, transition|
MailerService.order_confirmation(order).deliver
end
end
状態管理したいクラスでincludeする
code:ruby
class Order < ActiveRecord::Base
has_many :order_transitions, autosave: false
include Statesman::Adapters::ActiveRecordQueries[
transition_class: OrderTransition,
initial_state: :pending
]
def state_machine
@state_machine ||= OrderStateMachine.new(self, transition_class: OrderTransition)
end
end
上記例だとstate_machine経由で状態遷移に関するメソッドを呼び出す必要あり。delegateしてもよい
状態遷移のガードをしたり、コールバックを書くことが出来る
code:shell
$ rails g statesman:active_record_transition Order OrderTransition
Orderの状態遷移がOrderTransitionテーブルに記録される
workflow
2022年に1回リリースがあるがだいぶリリースされてない
3.0.0 - May 29, 2022 (15KB)
2.0.2 - May 31, 2019 (16.5KB)
2.0.1 - April 11, 2019 (17KB)
2.0.0 - January 12, 2019 (17KB)
2.0.0.pre - January 08, 2019 (18.5KB)
transitions
2022年に1回リリースがあるがだいぶリリースされてない
1.3.0 - March 31, 2022 (18.5KB)
1.2.1 - November 07, 2016 (18.5KB)
1.2.0 - September 21, 2016 (18.5KB)
1.1.1 - May 02, 2016 (18.5KB)
1.1.0 - April 08, 2016 (18KB)
https://gyazo.com/e2f9b325bf0b5ec4c41510ce7f88373c
state_machines
2017年の0.5.0以降にリリースがない
https://gyazo.com/a2622545b2c8511b9acc6f8207d33986