mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
Allow namespacing methods and state constants
This commit is contained in:
parent
5b885c8a0d
commit
86126c7c90
4 changed files with 115 additions and 5 deletions
|
@ -29,6 +29,9 @@ module AASM
|
|||
|
||||
configure :enum, nil
|
||||
|
||||
# Set to true to namespace reader methods and constants
|
||||
configure :namespace, false
|
||||
|
||||
# make sure to raise an error if no_direct_assignment is enabled
|
||||
# and attribute is directly assigned though
|
||||
@klass.class_eval %Q(
|
||||
|
@ -66,18 +69,30 @@ module AASM
|
|||
def state(name, options={})
|
||||
@state_machine.add_state(name, @klass, options)
|
||||
|
||||
if @klass.instance_methods.include?("#{name}?")
|
||||
if namespace?
|
||||
method_name = "#{namespace}_#{name}"
|
||||
else
|
||||
method_name = name
|
||||
end
|
||||
|
||||
if @klass.instance_methods.include?("#{method_name}?")
|
||||
warn "#{@klass.name}: The state name #{name} is already used!"
|
||||
end
|
||||
|
||||
@klass.class_eval <<-EORUBY, __FILE__, __LINE__ + 1
|
||||
def #{name}?
|
||||
def #{method_name}?
|
||||
aasm(:#{@name}).current_state == :#{name}
|
||||
end
|
||||
EORUBY
|
||||
|
||||
unless @klass.const_defined?("STATE_#{name.upcase}")
|
||||
@klass.const_set("STATE_#{name.upcase}", name)
|
||||
if namespace?
|
||||
const_name = "STATE_#{namespace.upcase}_#{name.upcase}"
|
||||
else
|
||||
const_name = "STATE_#{name.upcase}"
|
||||
end
|
||||
|
||||
unless @klass.const_defined?(const_name)
|
||||
@klass.const_set(const_name, name)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -148,5 +163,16 @@ module AASM
|
|||
end
|
||||
end
|
||||
|
||||
def namespace?
|
||||
!!@state_machine.config.namespace
|
||||
end
|
||||
|
||||
def namespace
|
||||
if @state_machine.config.namespace == true
|
||||
@name
|
||||
else
|
||||
@state_machine.config.namespace
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,5 +19,8 @@ module AASM
|
|||
attr_accessor :no_direct_assignment
|
||||
|
||||
attr_accessor :enum
|
||||
|
||||
# namespace reader methods and constants
|
||||
attr_accessor :namespace
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
28
spec/models/namespaced_multiple_example.rb
Normal file
28
spec/models/namespaced_multiple_example.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
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_review do
|
||||
transitions :from => :unapproved, :to => :approved
|
||||
end
|
||||
|
||||
event :unapprove_review do
|
||||
transitions :from => :approved, :to => :unapproved
|
||||
end
|
||||
end
|
||||
end
|
53
spec/unit/namespaced_multiple_example_spec.rb
Normal file
53
spec/unit/namespaced_multiple_example_spec.rb
Normal file
|
@ -0,0 +1,53 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'state machine' do
|
||||
let(:namespaced) { NamespacedMultipleExample.new }
|
||||
|
||||
it 'starts with an initial state' do
|
||||
expect(namespaced.aasm(:status).current_state).to eq(:unapproved)
|
||||
expect(namespaced).to respond_to(:unapproved?)
|
||||
expect(namespaced).to be_unapproved
|
||||
|
||||
expect(namespaced.aasm(:review_status).current_state).to eq(:unapproved)
|
||||
expect(namespaced).to respond_to(:review_unapproved?)
|
||||
expect(namespaced).to be_review_unapproved
|
||||
end
|
||||
|
||||
it 'allows transitions to other states' do
|
||||
expect(namespaced).to respond_to(:approve)
|
||||
expect(namespaced).to respond_to(:approve!)
|
||||
namespaced.approve!
|
||||
expect(namespaced).to respond_to(:approved?)
|
||||
expect(namespaced).to be_approved
|
||||
|
||||
expect(namespaced).to respond_to(:approve_review)
|
||||
expect(namespaced).to respond_to(:approve_review!)
|
||||
namespaced.approve_review!
|
||||
expect(namespaced).to respond_to(:review_approved?)
|
||||
expect(namespaced).to be_review_approved
|
||||
end
|
||||
|
||||
it 'denies transitions to other states' do
|
||||
expect {namespaced.unapprove}.to raise_error(AASM::InvalidTransition)
|
||||
expect {namespaced.unapprove!}.to raise_error(AASM::InvalidTransition)
|
||||
namespaced.approve
|
||||
expect {namespaced.approve}.to raise_error(AASM::InvalidTransition)
|
||||
expect {namespaced.approve!}.to raise_error(AASM::InvalidTransition)
|
||||
namespaced.unapprove
|
||||
|
||||
expect {namespaced.unapprove_review}.to raise_error(AASM::InvalidTransition)
|
||||
expect {namespaced.unapprove_review!}.to raise_error(AASM::InvalidTransition)
|
||||
namespaced.approve_review
|
||||
expect {namespaced.approve_review}.to raise_error(AASM::InvalidTransition)
|
||||
expect {namespaced.approve_review!}.to raise_error(AASM::InvalidTransition)
|
||||
namespaced.unapprove_review
|
||||
end
|
||||
|
||||
it 'defines constants for each state name' do
|
||||
expect(NamespacedMultipleExample::STATE_UNAPPROVED).to eq(:unapproved)
|
||||
expect(NamespacedMultipleExample::STATE_APPROVED).to eq(:approved)
|
||||
|
||||
expect(NamespacedMultipleExample::STATE_REVIEW_UNAPPROVED).to eq(:unapproved)
|
||||
expect(NamespacedMultipleExample::STATE_REVIEW_APPROVED).to eq(:approved)
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue