このパッケージには、Rubyクラスに有限状態マシンを追加するためのライブラリであるASMが含まれています。
ASMはACTS_AS_STATE_MACHINEプラグインとして始まりましたが、ActiverCordモデルのみをターゲットにしないより一般的なライブラリに進化しました。現在、多くのORMにアダプターを提供していますが、どんな親クラスがあるとしても、Rubyクラスには使用できます(もしあれば)。
詳細については、readme_from_version_3_to_4をご覧ください。
状態マシンを追加することは、AASMモジュールを含めるのと同じくらい簡単で、遷移とともに状態とイベントの定義を開始します。
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
transitions from : [ :running , :cleaning ] , to : :sleeping
end
end
endこれにより、クラスJobのインスタンスのためのいくつかの公開方法が提供されます。
job = Job . new
job . sleeping? # => true
job . may_run? # => true
job . run
job . running? # => true
job . sleeping? # => false
job . may_run? # => false
job . run # => raises AASM::InvalidTransition例外が気に入らず、応答として単純なtrueまたはfalseを好む場合は、 whingにならないように告げます。
class Job
...
aasm whiny_transitions : false do
...
end
end
job . running? # => true
job . may_run? # => false
job . run # => falseイベントを発射すると、ブロックをメソッドに渡すことができます。遷移が成功した場合にのみ呼び出されます。
job . run do
job . user . notify_job_ran # Will be called if job.may_run? is true
endイベント、移行、および状態の多くのコールバックを定義できます。これらの方法、PROC、またはクラスは、特定の状態に入るなど、特定の基準が満たされたときに呼び出されます。
class Job
include AASM
aasm do
state :sleeping , initial : true , before_enter : :do_something
state :running , before_enter : Proc . new { do_something && notify_somebody }
state :finished
after_all_transitions :log_status_change
event :run , after : :notify_somebody do
before do
log ( 'Preparing to run' )
end
transitions from : :sleeping , to : :running , after : Proc . new { |* args | set_process ( * args ) }
transitions from : :running , to : :finished , after : LogRunTime
end
event :sleep do
after do
...
end
error do | e |
...
end
transitions from : :running , to : :sleeping
end
end
def log_status_change
puts "changing from #{ aasm . from_state } to #{ aasm . to_state } (event: #{ aasm . current_event } )"
end
def set_process ( name )
...
end
def do_something
...
end
def notify_somebody
...
end
end
class LogRunTime
def call
log "Job was running for X seconds"
end
endこの場合、 do_something実際に州のsleepingに入る前に呼び出されますが、 notify_somebody移行run ( sleepingからrunningまで)が終了した後に呼び出されます。
また、上記の例でrunningからfinishedまでの移行後、ASMはLogRunTime初期化し、 callメソッドを実行します。このように、初期化メソッドを定義することにより、クラスに引数を渡すことができます。
Procsはレコードのコンテキストで実行されることに注意してください。これは、レコードを引数として期待する必要がないことを意味し、必要な方法を呼び出すだけです。
class LogRunTime
# optional args parameter can be omitted, but if you define initialize
# you must accept the model instance as the first parameter to it.
def initialize ( job , args = { } )
@job = job
end
def call
log "Job was running for #{ @job . run_time } seconds"
end
end パラメーターをイベントに渡すことができます。
job = Job . new
job . run ( :defragmentation )すべての警備員とコールバックの後にこれらのパラメーターを受け取ります。この場合、 set_process :defragmentationのように呼び出されます。
イベントの最初の議論が状態(例:runningまたは:finished )である場合、最初の引数が消費され、状態マシンはその状態に移行しようとします。ガードとコールバックのコンマ分離パラメーターを追加します
job = Job . new
job . run ( :running , :defragmentation )この場合、 set_processが呼び出されません、ジョブはランニングステートに移行し、コール:defragmentation
イベントの処理中にエラーが発生した場合、エラーが救助され、 :errorこれにより、それを処理したり、さらなる伝播のために再作成したりできます。
また、任意のイベントが失敗した場合に呼び出されるメソッドを定義できます。
def aasm_event_failed ( event_name , old_state_name )
# use custom exception/messages, report metrics, etc
endトランジション中:after (そしてその時点でのみ、またはグローバルafter_all_transitionsコールバック)、次のように、発生状態(州から)とターゲット状態(To State)にアクセスできます。
def set_process ( name )
logger . info "from #{ aasm . from_state } to #{ aasm . to_state } "
end ここでは、可能なすべてのコールバックのリストと、次のように表示できます。
begin
event before_all_events
event before
event guards
transition guards
old_state before_exit
old_state exit
after_all_transitions
transition after
new_state before_enter
new_state enter
... update state ...
event before_success # if persist successful
transition success # if persist successful, database update not guaranteed
event success # if persist successful, database update not guaranteed
old_state after_exit
new_state after_enter
event after
event after_all_events
rescue
event error
event error_on_all_events
ensure
event ensure
event ensure_on_all_events
endデータベースの更新後に起動する必要がある場合は、イベントのafter_commitコールバックを使用します。
コールバックを実行している間、 aasm.current_eventを使用してトリガーされたイベントの名前を簡単に取得できます。
# taken the example callback from above
def do_something
puts "triggered #{ aasm . current_event } "
endその後
job = Job . new
# without bang
job . sleep # => triggered :sleep
# with bang
job . sleep! # => triggered :sleep!定義された条件が与えられた場合にのみ、特定の移行を許可したいと仮定しましょう。このためには、移行ごとにガードを設定することができます。これは、実際にトランジションを実行する前に実行されます。警備員がfalse返す場合、遷移は拒否されます( AASM::InvalidTransitionを上げます):
class Cleaner
include AASM
aasm do
state :idle , initial : true
state :cleaning
event :clean do
transitions from : :idle , to : :cleaning , guard : :cleaning_needed?
end
event :clean_if_needed do
transitions from : :idle , to : :cleaning do
guard do
cleaning_needed?
end
end
transitions from : :idle , to : :idle
end
event :clean_if_dirty do
transitions from : :idle , to : :cleaning , guard : :if_dirty?
end
end
def cleaning_needed?
false
end
def if_dirty? ( status )
status == :dirty
end
end
job = Cleaner . new
job . may_clean? # => false
job . clean # => raises AASM::InvalidTransition
job . may_clean_if_needed? # => true
job . clean_if_needed! # idle
job . clean_if_dirty ( :clean ) # => raises AASM::InvalidTransition
job . clean_if_dirty ( :dirty ) # => true多くの警備員を提供することもできます。これはすべて続行するために成功する必要があります
def walked_the_dog? ; ... ; end
event :sleep do
transitions from : :running , to : :sleeping , guards : [ :cleaning_needed? , :walked_the_dog? ]
endイベント内のすべての移行にガードを提供したい場合は、イベントガードを使用できます
event :sleep , guards : [ :walked_the_dog? ] do
transitions from : :running , to : :sleeping , guards : [ :cleaning_needed? ]
transitions from : :cleaning , to : :sleeping
endよりRubyのようなガードの構文を好む場合は、 ifとunlessに使用できます。
event :clean do
transitions from : :running , to : :cleaning , if : :cleaning_needed?
end
event :sleep do
transitions from : :running , to : :sleeping , unless : :cleaning_needed?
end
endクラスがcallに応答した場合、メソッドの代わりにクラスを呼び出すことができます
event :sleep do
transitions from : :running , to : :sleeping , guards : Dog
end class Dog
def call
cleaning_needed? && walked?
end
...
endイベントに複数の遷移がある場合、正常に完了した最初の移行は、同じイベントで他の移行が処理されないようにします。
require 'aasm'
class Job
include AASM
aasm do
state :stage1 , initial : true
state :stage2
state :stage3
state :completed
event :stage1_completed do
transitions from : :stage1 , to : :stage3 , guard : :stage2_completed?
transitions from : :stage1 , to : :stage2
end
end
def stage2_completed?
true
end
end
job = Job . new
job . stage1_completed
job . aasm . current_state # stage3次from省略により、定義された状態からの移行を定義できます。
event :abort do
transitions to : :aborted
endstateの表示名を定義できます:表示オプションディスプレイ
class Job
include AASM
aasm do
state :stage1 , initial : true , display : 'First Stage'
state :stage2
state :stage3
end
end
job = Job . new
job . aasm . human_stateクラスごとに複数の状態マシンがサポートされています。ただし、クラスごとに1つのステートマシンを念頭に置いて、 ASMが構築されていることに注意してください。それにもかかわらず、ここにそれを行う方法があります(以下を参照)。関連状態が保存される場所については、データベース列を指定する必要があることに注意してください。以下の例で2つの列move_stateとwork_stateを指定しました。詳細については、列名と移行セクションを参照してください。
class SimpleMultipleExample
include AASM
aasm ( :move , column : 'move_state' ) do
state :standing , initial : true
state :walking
state :running
event :walk do
transitions from : :standing , to : :walking
end
event :run do
transitions from : [ :standing , :walking ] , to : :running
end
event :hold do
transitions from : [ :walking , :running ] , to : :standing
end
end
aasm ( :work , column : 'work_state' ) do
state :sleeping , initial : true
state :processing
event :start do
transitions from : :sleeping , to : :processing
end
event :stop do
transitions from : :processing , to : :sleeping
end
end
end
simple = SimpleMultipleExample . new
simple . aasm ( :move ) . current_state
# => :standing
simple . aasm ( :work ) . current_state
# => :sleeping
simple . start
simple . aasm ( :move ) . current_state
# => :standing
simple . aasm ( :work ) . current_state
# => :processing ASMは、複数の州のマシンで同じイベントを定義することを禁止していません。名前空間が提供されていない場合、最新の定義が「勝ち」、以前の定義をオーバーライドします。それにもかかわらず、警告が発行されます: SimpleMultipleExample: overriding method 'run'! 。
または、各ステートマシンに名前空間を提供することもできます。
class NamespacedMultipleExample
include AASM
aasm ( :status ) do
state :unapproved , initial : true
state :approved
event :approve do
transitions from : :unapproved , to : :approved
end
event :unapprove do
transitions from : :approved , to : :unapproved
end
end
aasm ( :review_status , namespace : :review ) do
state :unapproved , initial : true
state :approved
event :approve do
transitions from : :unapproved , to : :approved
end
event :unapprove do
transitions from : :approved , to : :unapproved
end
end
end
namespaced = NamespacedMultipleExample . new
namespaced . aasm ( :status ) . current_state
# => :unapproved
namespaced . aasm ( :review_status ) . current_state
# => :unapproved
namespaced . approve_review
namespaced . aasm ( :review_status ) . current_state
# => :approvedすべてのクラスおよびインスタンスレベルのAASMメソッドaasm 、ステートマシンセレクターを受け入れます。したがって、たとえば、クラスレベルで検査を使用するには、使用する必要があります
SimpleMultipleExample . aasm ( :move ) . states . map ( & :name )
# => [:standing, :walking, :running]イベントを別のイベントにバインドします
class Example
include AASM
aasm ( :work ) do
state :sleeping , initial : true
state :processing
event :start do
transitions from : :sleeping , to : :processing
end
event :stop do
transitions from : :processing , to : :sleeping
end
end
aasm ( :question ) do
state :answered , initial : true
state :asked
event :ask , binding_event : :start do
transitions from : :answered , to : :asked
end
event :answer , binding_event : :stop do
transitions from : :asked , to : :answered
end
end
end
example = Example . new
example . aasm ( :work ) . current_state #=> :sleeping
example . aasm ( :question ) . current_state #=> :answered
example . ask
example . aasm ( :work ) . current_state #=> :processing
example . aasm ( :question ) . current_state #=> :askedASMは各ステータスの定数を自動的に生成するため、それらを明示的に定義する必要はありません。
class Foo
include AASM
aasm do
state :initialized
state :calculated
state :finalized
end
end
> Foo :: STATE_INITIALIZED
#=> :initialized
> Foo :: STATE_CALCULATED
#=> :calculatedASMを使用すると、自分のアプリケーションを目的とするために、 AASM::Baseを簡単に拡張できます。
多くのAASMモデルに共通のロジックがあるとしましょう。このロジックはAASM::Baseのサブクラスで具体化できます。
class CustomAASMBase < AASM :: Base
# A custom transition that we want available across many AASM models.
def count_transitions!
klass . class_eval do
aasm with_klass : CustomAASMBase do
after_all_transitions :increment_transition_count
end
end
end
# A custom annotation that we want available across many AASM models.
def requires_guards!
klass . class_eval do
attr_reader :authorizable_called ,
:transition_count ,
:fillable_called
def authorizable?
@authorizable_called = true
end
def fillable?
@fillable_called = true
end
def increment_transition_count
@transition_count ||= 0
@transition_count += 1
end
end
end
end AASM Stateマシンを備えたモデルを宣言すると、AASMブロックをaasmブロックを宣言し:with_klassキーを自分のクラスに宣言します。
class SimpleCustomExample
include AASM
# Let's build an AASM state machine with our custom class.
aasm with_klass : CustomAASMBase do
requires_guards!
count_transitions!
state :initialised , initial : true
state :filled_out
state :authorised
event :fill_out do
transitions from : :initialised , to : :filled_out , guard : :fillable?
end
event :authorise do
transitions from : :filled_out , to : :authorised , guard : :authorizable?
end
end
endASMにはActivereCordのサポートが付属しており、データベース内のオブジェクトの状態を自動的に持続させることができます。
gem 'after_commit_everywhere', '~> 1.0' gemfileに追加します。
class Job < ActiveRecord :: Base
include AASM
aasm do # default column: aasm_state
state :sleeping , initial : true
state :running
event :run do
transitions from : :sleeping , to : :running
end
event :sleep do
transitions from : :running , to : :sleeping
end
end
endオブジェクトを自動保存するか、救われていないままにしておくことができます
job = Job . new
job . run # not saved
job . run! # saved
# or
job . aasm . fire ( :run ) # not saved
job . aasm . fire! ( :run ) # saved保存には、 Jobクラスですべての検証を実行することが含まれます。 whiny_persistenceフラグがtrueに設定されている場合、障害の場合に例外が提起されます。 whiny_persistenceフラグがfalseに設定されている場合、状態の遷移が成功した場合、またはエラーが発生した場合にfalse場合、バンを持つ方法がtrue返します。
検証を実行せずに状態が保存されるようにしたい場合(そして、それにより、無効なオブジェクト状態を持続する可能性があります)、単に検証をスキップするようにASMに伝えます。検証をスキップするときは、データベースで状態列のみが更新されることに注意してください(ActivereCord update_columnが機能しているように)。
class Job < ActiveRecord :: Base
include AASM
aasm skip_validation_on_save : true do
state :sleeping , initial : true
state :running
event :run do
transitions from : :sleeping , to : :running
end
event :sleep do
transitions from : :running , to : :sleeping
end
end
endまた、 some_event_name_without_validation!方法。これにより、デフォルトですべての移行について検証を行う柔軟性があり、必要に応じてスキップします。上記の例で述べたように、状態列のみが更新されることに注意してください。
job . run_without_validation!状態を保存するためのAASM列が直接割り当てられていないことを確認する場合は、次のように直接割り当てを許可しないように設定します。
class Job < ActiveRecord :: Base
include AASM
aasm no_direct_assignment : true do
state :sleeping , initial : true
state :running
event :run do
transitions from : :sleeping , to : :running
end
end
endこれにつながります:
job = Job . create
job . aasm_state # => 'sleeping'
job . aasm_state = :running # => raises AASM::NoDirectAssignmentError
job . aasm_state # => 'sleeping'新しい状態が入力されるたびにタイムスタンプを書こうとするようにASMに伝えることができます。 timestamps: trueが設定されている場合、 ASMは新しい状態と_atのような名前のあるフィールドを探し、それを記入しようとします:
class Job < ActiveRecord :: Base
include AASM
aasm timestamps : true do
state :sleeping , initial : true
state :running
event :run do
transitions from : :sleeping , to : :running
end
end
endこれにつながります:
job = Job . create
job . running_at # => nil
job . run!
job . running_at # => 2020-02-20 20:00:00欠落しているタイムスタンプフィールドは静かに無視されているため、このオプションを使用する際には、すべての状態に対してセッター(ActiverCord列など)を持つ必要はありません。
状態列には、Rails 4.1+で列挙を使用できます。
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列挙マッピングへのアクセスをenumの値として提供するメソッドの名前を明示的に渡すことができます。または、単にそれをtrueに設定することもできます。後者の場合、ASMは複数形の列名を使用して可能な列挙状態にアクセスしようとします。
さらに、列の整数型(通常、Rails Enumsを使用している場合は通常)がある場合、省略:enum Setted --- AASM Autoがこの状況を検出し、列挙サポートを有効にします。何か問題が発生した場合は、Enum機能を無効にし、enum :enum to falseによってデフォルトの動作に戻ることができます。
Asmは、 ActiverecordとMongoid以外の続編もサポートしています。
class Job < Sequel :: Model
include AASM
aasm do # default column: aasm_state
...
end
endただし、 ActivereCordほど機能していません。たとえば、スコープはまだ定義されています。自動スコープを参照してください。
バージョン4.8.0以来、 AASMは永続性ORMとしてのDynamoidもサポートしています。
Mongoidを使用している場合、ASMはMongodbの持続性もサポートします。 ASMを含める前に、Mongoid ::文書を含めるようにしてください。
class Job
include Mongoid :: Document
include AASM
field :aasm_state
aasm do
...
end
endASMは、Nobrainerを使用している場合、RethinkDBの持続性もサポートします。 ASMを含める前に、必ずNobrainer ::ドキュメントを含めるようにしてください。
class Job
include NoBrainer :: Document
include AASM
field :aasm_state
aasm do
...
end
endASMは、Redis :: Objectsを介したRedisの持続性もサポートします。 ASMを含める前に、必ずRedis ::オブジェクトを含めるようにしてください。バン以外のイベントは、すべての呼び出しの変更を維持するために、Bangイベントとして機能することに注意してください。
class User
include Redis :: Objects
include AASM
aasm do
end
endASMは、モデル内の各状態のスコープメソッドを自動的に作成します。
class Job < ActiveRecord :: Base
include AASM
aasm do
state :sleeping , initial : true
state :running
state :cleaning
end
def self . sleeping
"This method name is already in use"
end
end class JobsController < ApplicationController
def index
@running_jobs = Job . running
@recent_cleaning_jobs = Job . cleaning . where ( 'created_at >= ?' , 3 . days . ago )
# @sleeping_jobs = Job.sleeping #=> "This method name is already in use"
end
endスコープを必要としない場合(または単にそれらを望まない)場合は、 AASM状態を定義するときに作成を無効にします。
class Job < ActiveRecord :: Base
include AASM
aasm create_scopes : false do
state :sleeping , initial : true
state :running
state :cleaning
end
endバージョン3.0.13以降、AASMはActiverCordトランザクションをサポートしています。したがって、トランジションコールバックまたは状態の更新が失敗するたびに、データベースレコードのすべての変更がロールバックされます。 MongoDBはトランザクションをサポートしていません。
現在、イベントで処理できる3つのトランザクションコールバックと、すべてのイベントに2つのトランザクションコールバックがあります。
event before_all_transactions
event before_transaction
event aasm_fire_event ( within transaction )
event after_commit ( if event successful )
event after_transaction
event after_all_transactionsトランザクションがコミットされた後にのみ依存するアクションが発生することを確認する場合は、このようなAuto-Save(BANG)メソッドとともにafter_commitコールバックを使用します。
class Job < ActiveRecord :: Base
include AASM
aasm do
state :sleeping , initial : true
state :running
event :run , after_commit : :notify_about_running_job do
transitions from : :sleeping , to : :running
end
end
def notify_about_running_job
...
end
end
job = Job . where ( state : 'sleeping' ) . first!
job . run! # Saves the model and triggers the after_commit callback Auto-Saveメソッドは使用されないため、以下はafter_commitコールバックを実行しないことに注意してください。
job = Job . where ( state : 'sleeping' ) . first!
job . run
job . save! #notify_about_running_job is not run次のことに注意してください:after_commit AASMコールバックは、実際のDBトランザクションではなく、トランザクションパターンのカスタム実装を中心に動作します。この事実は、ネストされたトランザクション内でレース条件と冗長コールバックコールを引き起こします。 gem 'after_commit_everywhere', '~> 1.0' Gemfileに追加することを強くお勧めします。
独自のトランザクション内で状態の変更をカプセル化したい場合、このネストされたトランザクションの動作は混乱する可能性があります。これについてもっと知りたい場合は、ActiverCordネストされたトランザクションをご覧ください。それにもかかわらず、デフォルトでは新しいトランザクションtransaction(requires_new: true) 。構成を変更することにより、この動作をオーバーライドできます
class Job < ActiveRecord :: Base
include AASM
aasm requires_new_transaction : false do
...
end
...
endその後、 transaction(requires_new: false) 、Railsデフォルトにつながります。
さらに、ActiverCordのアクションをトランザクションにラップしたくない場合は、 use_transactionsフラグを指定できます。これは、何らかのエラーが発生した場合でも、トランザクションまたはコールバックの結果として発生するデータベースに物事を維持したい場合に役立ちます。 use_transactionsフラグはデフォルトで真です。
class Job < ActiveRecord :: Base
include AASM
aasm use_transactions : false do
...
end
...
endASMは、データベースの永続性レイヤーのためにwith_lock経由でactiverecordの悲観的なロックをサポートします。
| オプション | 目的 |
|---|---|
false (デフォルト) | ロックは取得されません |
true | FOR UPDATEブロッキング悲観的ロックを取得します |
| 弦 | FOR UPDATE NOWAIT SQL文字列EGに基づいてロックを取得します |
class Job < ActiveRecord :: Base
include AASM
aasm requires_lock : true do
...
end
...
end class Job < ActiveRecord :: Base
include AASM
aasm requires_lock : 'FOR UPDATE NOWAIT' do
...
end
...
endデフォルトとして、AASMは列aasm_stateを使用して状態を保存します。次のような:columnを使用して、お気に入りの列名を定義することでこれをオーバーライドできます。
class Job < ActiveRecord :: Base
include AASM
aasm column : :my_state do
...
end
aasm :another_state_machine , column : :second_state do
...
end
end列名を使用するものは何でも、[型文字stringの)この列を提供するために移行を追加してください。データベースレベルで列のデフォルト値を追加しないでください。データベースにデフォルト値を追加すると、モデルのインスタンス化時に初期状態のASMコールバックが起動されません。
class AddJobState < ActiveRecord :: Migration
def self . up
add_column :jobs , :aasm_state , :string
end
def self . down
remove_column :jobs , :aasm_state
end
endロギング状態の変更は、Paper_trail Gemを使用して行うことができます
実装の例は、https://github.com/nitsujri/aasm-papertrail-exampleで見つけることができます
ASMは、状態とイベントのクエリメソッドをサポートします
次のJobクラスを考えると、
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 , guard : :cleaning_needed?
end
event :sleep do
transitions from : [ :running , :cleaning ] , to : :sleeping
end
end
def cleaning_needed?
false
end
end # show all states
Job . aasm . states . map ( & :name )
#=> [:sleeping, :running, :cleaning]
job = Job . new
# show all permitted states (from initial state)
job . aasm . states ( permitted : true ) . map ( & :name )
#=> [:running]
# List all the permitted transitions(event and state pairs) from initial state
job . aasm . permitted_transitions
#=> [{ :event => :run, :state => :running }]
job . run
job . aasm . states ( permitted : true ) . map ( & :name )
#=> [:sleeping]
# show all non permitted states
job . aasm . states ( permitted : false ) . map ( & :name )
#=> [:cleaning]
# show all possible (triggerable) events from the current state
job . aasm . events . map ( & :name )
#=> [:clean, :sleep]
# show all permitted events
job . aasm . events ( permitted : true ) . map ( & :name )
#=> [:sleep]
# show all non permitted events
job . aasm . events ( permitted : false ) . map ( & :name )
#=> [:clean]
# show all possible events except a specific one
job . aasm . events ( reject : :sleep ) . map ( & :name )
#=> [:clean]
# list states for select
Job . aasm . states_for_select
#=> [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
# show permitted states with guard parameter
job . aasm . states ( { permitted : true } , guard_parameter ) . map ( & :name )警告はデフォルトでSTDERRに印刷されます。これらの警告を別の出力にログインしたい場合は、使用してください
class Job
include AASM
aasm logger : Rails . logger do
...
end
end AASM::Configuration.hide_warnings = trueを設定して、警告を非表示にできます
今ではCodedataqueryをサポートしています!しかし、私はまだ互換性の更新をリポジトリに送信する過程にあります。それまでの間、私のフォークを使用することができますが、まだいくつかの小さな問題があるかもしれませんが、自分で広く使用するつもりなので、修正は速くなるはずです。
警告:
ASMはRSPECのマッチャーを提供します。
transition_from 、have_state 、 allow_eventallow_transition_to 。 spec_helper.rbファイルにrequire 'aasm/rspec' 。 # classes with only the default state machine
job = Job . new
expect ( job ) . to transition_from ( :sleeping ) . to ( :running ) . on_event ( :run )
expect ( job ) . not_to transition_from ( :sleeping ) . to ( :cleaning ) . on_event ( :run )
expect ( job ) . to have_state ( :sleeping )
expect ( job ) . not_to have_state ( :running )
expect ( job ) . to allow_event :run
expect ( job ) . to_not allow_event :clean
expect ( job ) . to allow_transition_to ( :running )
expect ( job ) . to_not allow_transition_to ( :cleaning )
# on_event also accept multiple arguments
expect ( job ) . to transition_from ( :sleeping ) . to ( :running ) . on_event ( :run , :defragmentation )
# classes with multiple state machine
multiple = SimpleMultipleExample . new
expect ( multiple ) . to transition_from ( :standing ) . to ( :walking ) . on_event ( :walk ) . on ( :move )
expect ( multiple ) . to_not transition_from ( :standing ) . to ( :running ) . on_event ( :walk ) . on ( :move )
expect ( multiple ) . to have_state ( :standing ) . on ( :move )
expect ( multiple ) . not_to have_state ( :walking ) . on ( :move )
expect ( multiple ) . to allow_event ( :walk ) . on ( :move )
expect ( multiple ) . to_not allow_event ( :hold ) . on ( :move )
expect ( multiple ) . to allow_transition_to ( :walking ) . on ( :move )
expect ( multiple ) . to_not allow_transition_to ( :running ) . on ( :move )
expect ( multiple ) . to transition_from ( :sleeping ) . to ( :processing ) . on_event ( :start ) . on ( :work )
expect ( multiple ) . to_not transition_from ( :sleeping ) . to ( :sleeping ) . on_event ( :start ) . on ( :work )
expect ( multiple ) . to have_state ( :sleeping ) . on ( :work )
expect ( multiple ) . not_to have_state ( :processing ) . on ( :work )
expect ( multiple ) . to allow_event ( :start ) . on ( :move )
expect ( multiple ) . to_not allow_event ( :stop ) . on ( :move )
expect ( multiple ) . to allow_transition_to ( :processing ) . on ( :move )
expect ( multiple ) . to_not allow_transition_to ( :sleeping ) . on ( :move )
# allow_event also accepts arguments
expect ( job ) . to allow_event ( :run ) . with ( :defragmentation ) ASMは、MinitestにアサーションとRSPECのような期待を提供します。
サポートされているアサーションのリスト: assert_have_state 、 refute_have_state 、 assert_transitions_from 、 refute_transitions_from 、 assert_event_allowed 、 refute_event_allowed 、 assert_transition_to_allowed 、 refute_transition_to_allowed 。
追加のrequire 'aasm/minitest' test_helper.rbファイルに必要です。
# classes with only the default state machine
job = Job . new
assert_transitions_from job , :sleeping , to : :running , on_event : :run
refute_transitions_from job , :sleeping , to : :cleaning , on_event : :run
assert_have_state job , :sleeping
refute_have_state job , :running
assert_event_allowed job , :run
refute_event_allowed job , :clean
assert_transition_to_allowed job , :running
refute_transition_to_allowed job , :cleaning
# on_event also accept arguments
assert_transitions_from job , :sleeping , :defragmentation , to : :running , on_event : :run
# classes with multiple state machine
multiple = SimpleMultipleExample . new
assert_transitions_from multiple , :standing , to : :walking , on_event : :walk , on : :move
refute_transitions_from multiple , :standing , to : :running , on_event : :walk , on : :move
assert_have_state multiple , :standing , on : :move
refute_have_state multiple , :walking , on : :move
assert_event_allowed multiple , :walk , on : :move
refute_event_allowed multiple , :hold , on : :move
assert_transition_to_allowed multiple , :walking , on : :move
refute_transition_to_allowed multiple , :running , on : :move
assert_transitions_from multiple , :sleeping , to : :processing , on_event : :start , on : :work
refute_transitions_from multiple , :sleeping , to : :sleeping , on_event : :start , on : :work
assert_have_state multiple , :sleeping , on : :work
refute_have_state multiple , :processing , on : :work
assert_event_allowed multiple , :start , on : :move
refute_event_allowed multiple , :stop , on : :move
assert_transition_to_allowed multiple , :processing , on : :move
refute_transition_to_allowed multiple , :sleeping , on : :move サポートされている期待のリスト: must_transition_from 、 wont_transition_from 、 must_have_state 、 wont_have_state 、 must_allow_event 、 wont_allow_event 、 must_allow_transition_to 、 wont_allow_transition_to 。
追加するrequire 'aasm/minitest_spec' test_helper.rbファイルに必要です。
# classes with only the default state machine
job = Job . new
job . must_transition_from :sleeping , to : :running , on_event : :run
job . wont_transition_from :sleeping , to : :cleaning , on_event : :run
job . must_have_state :sleeping
job . wont_have_state :running
job . must_allow_event :run
job . wont_allow_event :clean
job . must_allow_transition_to :running
job . wont_allow_transition_to :cleaning
# on_event also accept arguments
job . must_transition_from :sleeping , :defragmentation , to : :running , on_event : :run
# classes with multiple state machine
multiple = SimpleMultipleExample . new
multiple . must_transition_from :standing , to : :walking , on_event : :walk , on : :move
multiple . wont_transition_from :standing , to : :running , on_event : :walk , on : :move
multiple . must_have_state :standing , on : :move
multiple . wont_have_state :walking , on : :move
multiple . must_allow_event :walk , on : :move
multiple . wont_allow_event :hold , on : :move
multiple . must_allow_transition_to :walking , on : :move
multiple . wont_allow_transition_to :running , on : :move
multiple . must_transition_from :sleeping , to : :processing , on_event : :start , on : :work
multiple . wont_transition_from :sleeping , to : :sleeping , on_event : :start , on : :work
multiple . must_have_state :sleeping , on : :work
multiple . wont_have_state :processing , on : :work
multiple . must_allow_event :start , on : :move
multiple . wont_allow_event :stop , on : :move
multiple . must_allow_transition_to :processing , on : :move
multiple . wont_allow_transition_to :sleeping , on : :move % gem install aasm # Gemfile
gem 'aasm'% rake build
% sudo gem install pkg/aasm-x.y.z.gemASMをインストールした後、ジェネレーターを実行できます。
% rails generate aasm NAME [COLUMN_NAME]名前をモデル名に置き換え、column_nameはオプションです(デフォルトは 'aasm_state')。これにより、モデルが作成され(存在しない場合)、ASMブロックで構成します。 ActiverCord ormの場合、移行ファイルが追加され、ASM状態列をテーブルに追加します。
Dockerで簡単にテストスイートを実行します
1. docker-compose build aasm
2. docker-compose run --rm aasm
現在のバージョンの最近の変更の詳細については、The Changelogをご覧ください。
お気軽に
aasmのタグ)について質問するこのソフトウェアは、「現状のまま」と、特定の目的に対する商品性と適合性の暗黙の保証を含む、明示的または黙示的な保証なしで提供されます。
著作権(c)2006-2017スコットバロン
このソフトウェアと関連するドキュメントファイル(「ソフトウェア」)のコピーを入手して、制限なしにソフトウェアを扱うために、このソフトウェアを制限する権利を含め、ソフトウェアのコピーをコピー、変更、公開、配布、販売する、ソフトウェアのコピーを許可する人を許可する人を許可することを含めて、許可が無料で許可されます。
上記の著作権通知とこの許可通知は、ソフトウェアのすべてのコピーまたはかなりの部分に含まれるものとします。
このソフトウェアは、商品性、特定の目的への適合性、および非侵害の保証を含むがこれらに限定されない、明示的または黙示的なものを保証することなく、「現状のまま」提供されます。いかなる場合でも、著者または著作権所有者は、契約、不法行為、またはその他の訴訟、ソフトウェアまたはソフトウェアの使用またはその他の取引に関連する、またはその他の契約、またはその他の請求、またはその他の責任について責任を負いません。