이 패키지에는 Ruby 클래스에 유한 상태 기계를 추가하기위한 라이브러리 인 AAMS가 포함되어 있습니다.
AASM은 ACTS_AS_STATE_MACHINE 플러그인으로 시작했지만 더 이상 ActiverEcord 모델만을 대상으로하지 않는보다 일반적인 라이브러리로 발전했습니다. 현재 많은 ORM에 어댑터를 제공하지만 어떤 부모 클래스가 있든 상관없이 Ruby 클래스에 사용할 수 있습니다 (있는 경우).
버전 3.x에서 4.0의 AAMS 로 전환하는 방법에 대해서는 readme_from_version_3_to_4를 살펴보십시오.
상태 머신을 추가하는 것은 AAMS 모듈을 포함하고 상태 및 이벤트를 전환 과 함께 정의하기 시작하는 것만 큼 간단합니다.
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 응답으로 선호한다면, Aasm을 말하지 말라고 말하십시오.
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이벤트, 전환 및 상태에 대한 여러 콜백을 정의 할 수 있습니다. 이러한 방법, Procs 또는 클래스는 특정 상태에 들어가는 것과 같은 특정 기준이 충족 될 때 호출됩니다.
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 에서 running 로) 완료된 후에 호출됩니다 sleeping
AAMS는 또한 위의 예제에서 running 에서 finished 로 전환 한 후 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
end표시 옵션을 사용하여 상태의 표시 이름을 정의 할 수 있습니다.
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 클래스 당 여러 상태 기계가 지원됩니다. AAMS는 클래스 당 하나의 상태 기계로 구축되었음을 알고 있어야합니다. 그럼에도 불구하고 다음은 수행 방법이 있습니다 (아래 참조). 관련 상태가 저장 될 위치에 대한 데이터베이스 열을 지정해야합니다. 아래 예제에서 두 개의 열 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 AAMS는 둘 이상의 상태 머신에서 동일한 이벤트를 정의하는 것을 금지하지 않습니다. 네임 스페이스가 제공되지 않으면 최신 정의가 "이기고"이전 정의를 무시합니다. 그럼에도 불구하고 경고가 발행됩니다 : 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 모든 AAMS 클래스 및 인스턴스 수준 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 #=> :askedAASM은 각 상태에 대한 상수를 자동으로 생성하므로 명시 적으로 정의 할 필요가 없습니다.
class Foo
include AASM
aasm do
state :initialized
state :calculated
state :finalized
end
end
> Foo :: STATE_INITIALIZED
#=> :initialized
> Foo :: STATE_CALCULATED
#=> :calculated AAMS를 사용하면 자신의 응용 프로그램 목적으로 AASM::Base 을 쉽게 확장 할 수 있습니다.
많은 AAMS 모델에서 공통 논리를 가지고 있다고 가정 해 봅시다. 우리는이 논리를 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 AAMS 상태 머신이있는 모델을 선언 할 때, 우리는 단순히 AASM 블록을 A :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
endAAMS는 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
endaasm을 말하거나 물체를 자동으로 구하거나 구원받지 못하게 할 수 있습니다.
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 .
유효성 검사를 실행하지 않고 상태가 저장되고 (유효하지 않은 객체 상태를 유지할 수 있음) 상태가 저장되도록하려면 AAMS에 유효성 검사를 건너 뛰도록 지시하십시오. 유효성 검사를 건너 뛰면 상태 열만 데이터베이스에서 업데이트됩니다 (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 열이 직접 할당되지 않은지 확인하려면 다음과 같이 직접 할당을 허용하지 않도록 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' 새로운 상태가 입력 될 때마다 타임 스탬프 를 작성하려고 시도 할 수 있습니다. timestamps: true 설정되면 AAMS는 새로운 상태 + _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누락 된 타임 스탬프 필드는 조용히 무시 되므로이 옵션을 사용할 때 모든 상태에 대한 세터 (예 : ActiveRecord 열)를 가질 필요는 없습니다.
주 열에는 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 로 설정할 수 있습니다. 후자의 경우 AASM은 복수형 열 이름을 사용하여 가능한 열거 상태에 액세스하려고 시도합니다.
또한 열에 정수 유형이있는 경우 (일반적으로 Rails Enums로 작업 할 때의 경우) :enum Setting --- AAMS 가이 상황을 자동 감지하고 ENABLEND ENUM 지원을 생략 할 수 있습니다. 문제가 발생하면 열거 기능을 비활성화하고 :enum 하여 false 동작으로 돌아갈 수 있습니다.
AASM은 또한 Activerecord 및 Mongoid 외에 속편을 지원합니다.
class Job < Sequel :: Model
include AASM
aasm do # default column: aasm_state
...
end
end그러나 ActiveRecord 만큼 아직 기능이 완성되지는 않습니다. 예를 들어, 아직 정의 된 스코프가 있습니다. 자동 스코프를 참조하십시오.
버전 4.8.0 이므로 AASM은 또한 Dynamoid를 지속성 ORM으로 지원합니다.
AASM은 또한 몽고이드를 사용하는 경우 MongoDB에 대한 지속성을지지합니다. AAMS를 포함시키기 전에 Mongoid :: 문서를 포함하십시오.
class Job
include Mongoid :: Document
include AASM
field :aasm_state
aasm do
...
end
endAAMS는 또한 NOBRAINER를 사용하는 경우 RethinkDB에 대한 지속성을 지원합니다. AAMS를 포함시키기 전에 nobrainer :: 문서를 포함 시키십시오.
class Job
include NoBrainer :: Document
include AASM
field :aasm_state
aasm do
...
end
endAAMS는 또한 Redis :: 물체를 통해 Redis의 지속성을 지원합니다. AAMS를 포함시키기 전에 Redis :: 물체를 포함 시키십시오. 비-뱅 이벤트는 Bang 이벤트로 작동하여 모든 통화의 변경 사항을 지속합니다.
class User
include Redis :: Objects
include AASM
aasm do
end
endAAMS는 모델의 각 상태에 대한 스코프 메소드를 자동으로 생성합니다.
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은 ActivereCord 트랜잭션을 지원합니다. 따라서 전환 콜백 또는 상태 업데이트가 실패 할 때마다 데이터베이스 레코드에 대한 모든 변경 사항이 롤백됩니다. 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 트랜잭션이 커밋 된 후에 만 해당 조치에 따라 발생하는지 확인하려면 after_commit 콜백을 사용하여 Auto-SAVE (BANG) 메소드를 사용하십시오.
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 자동 사원 메소드가 사용되지 않기 때문에 다음은 after_commit 콜백을 실행하지 않습니다.
job = Job . where ( state : 'sleeping' ) . first!
job . run
job . save! #notify_about_running_job is not run 이에 참조하십시오 :after_commit AAMS 콜백은 실제 DB 트랜잭션보다는 트랜잭션 패턴의 사용자 정의 구현을 중심으로 동작합니다. 이 사실은 여전히 중첩 거래 내에서 레이스 조건과 중복 콜백 호출을 유발합니다. 이를 고치기 위해 gem 'after_commit_everywhere', '~> 1.0' Gemfile 에 추가하는 것이 좋습니다.
자체 거래 내에서 상태 변경을 캡슐화하려면이 중첩 된 거래의 동작이 혼란 스러울 수 있습니다. 이것에 대해 더 알고 싶다면 ActiveRecord 중첩 트랜잭션을 살펴보십시오. 그럼에도 불구하고 기본적으로 AAMS에는 새로운 트랜잭션 transaction(requires_new: true) . 구성을 변경 하여이 동작을 무시할 수 있습니다
class Job < ActiveRecord :: Base
include AASM
aasm requires_new_transaction : false do
...
end
...
end 그런 다음 transaction(requires_new: false) , Rails 기본값.
또한, ActiveRecord 조치가 트랜잭션에 래핑되는 것을 원하지 않으면 use_transactions 플래그를 지정할 수 있습니다. 일부 오류가 발생하더라도 트랜잭션이나 콜백의 결과로 발생하는 데이터베이스에 물건을 지속하려면 유용 할 수 있습니다. use_transactions 플래그는 기본적으로 참입니다.
class Job < ActiveRecord :: Base
include AASM
aasm use_transactions : false do
...
end
...
end AAMS는 데이터베이스 지속성 계층의 with_lock 통해 ActivereCord 비관적 잠금을 지원합니다.
| 옵션 | 목적 |
|---|---|
false (기본값) | 잠금 장치는 얻지 못합니다 |
true | FOR UPDATE 비관적 잠금 장치를 얻으십시오 |
| 끈 | SQL 문자열을 기반으로 잠금을 얻으십시오 FOR UPDATE NOWAIT |
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 기본값으로 AAMS는 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 )을 제공하십시오. 데이터베이스 수준에서 열에 대한 기본값을 추가하지 마십시오. 데이터베이스에 기본값을 추가하면 모델의 인스턴스화시 초기 상태의 AASM 콜백이 해고되지 않습니다.
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 보석을 사용하여 수행 할 수 있습니다
구현의 예는 여기에서 https://github.com/nitsujri/aasm-papertrail-example을 참조하십시오
AAMS는 상태 및 사건에 대한 쿼리 방법을 지원합니다
다음 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를 지원합니다! 그러나 나는 여전히 저장소에 호환성 업데이트를 제출하는 과정에 있습니다. 그 동안 당신은 내 포크를 사용할 수 있지만 여전히 약간의 사소한 문제가있을 수 있지만 광범위하게 직접 사용하려고하므로 수정이 빠르게 나와야합니다.
경고 :
AAMS
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 ) AASM은 미니 테스트에 대한 주장과 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 .
Add add test_helper.rb 파일에 require 'aasm/minitest' 하고 다음과 같이 사용하십시오.
# 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 .
Add add test_helper.rb 파일에 require 'aasm/minitest_spec' 하고 다음과 같이 사용하십시오.
# 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.gemAasm을 설치 한 후 생성기를 실행할 수 있습니다.
% rails generate aasm NAME [COLUMN_NAME]이름을 모델 이름으로 바꾸고 column_name은 선택 사항입니다 (기본값은 'AASM_STATE'). 이것은 모델을 생성하고 (존재하지 않는 경우) AAMS 블록으로 구성합니다. ActiveRecord ORM의 경우 마이그레이션 파일이 추가되어 AMS 상태 열을 테이블에 추가합니다.
Docker에서 테스트 스위트를 쉽게 실행하십시오
1. docker-compose build aasm
2. docker-compose run --rm aasm
현재 버전의 최근 변경 사항에 대한 자세한 내용은 Changelog를 살펴보십시오.
자유롭게하십시오
aasm 와 태그)에 대한 질문을하십시오.이 소프트웨어는 "있는 그대로"제공되며 특정 목적에 대한 상품성 및 체력에 대한 묵시적 보증을 포함하여 명시 적 또는 묵시적 보증없이 제공됩니다.
저작권 (C) 2006-2017 Scott Barron
이에 따라이 소프트웨어 및 관련 문서 파일 ( "소프트웨어")의 사본을 얻는 사람에게는 허가가 부여됩니다. 소프트웨어의 사용, 복사, 수정, 합병, 배포, 배포, 숭고 및/또는 소프트웨어의 사본을 판매 할 권한을 포함하여 제한없이 소프트웨어를 처리 할 수 있도록 소프트웨어를 제공 할 권한이 없습니다.
위의 저작권 통지 및이 권한 통지는 소프트웨어의 모든 사본 또는 실질적인 부분에 포함되어야합니다.
이 소프트웨어는 상업성, 특정 목적에 대한 적합성 및 비 침해에 대한 보증을 포함하여 명시 적 또는 묵시적 보증없이 "그대로"제공됩니다. 어떠한 경우에도 저자 또는 저작권 보유자는 계약, 불법 행위 또는 기타, 소프트웨어 또는 소프트웨어의 사용 또는 기타 거래에서 발생하는 계약, 불법 행위 또는 기타의 행동에 관계없이 청구, 손해 또는 기타 책임에 대해 책임을지지 않습니다.