using Ruby method resolution to read the current state

This commit is contained in:
Thorsten Böttger 2013-04-24 12:57:06 +02:00
parent 7ab505ac2f
commit 3a331e89ca
11 changed files with 88 additions and 25 deletions

9
API Normal file
View File

@ -0,0 +1,9 @@
Overwrite method to read the current state
class MyClass
include AASM
def aasm_read_state
# retrieve the current state manually
end
end

View File

@ -81,6 +81,11 @@ module AASM
@aasm ||= AASM::InstanceBase.new(self)
end
# may be overwritten by persistence mixins
def aasm_read_state
aasm.enter_initial_state
end
# deprecated
def aasm_current_state
# warn "#aasm_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.state instead!"

View File

@ -6,7 +6,7 @@ module AASM
end
def current_state
@current_state ||= persistable? ? @instance.aasm_read_state : enter_initial_state
@current_state ||= @instance.aasm_read_state
end
def current_state=(state)
@ -77,11 +77,5 @@ module AASM
save_success
end
private
def persistable?
@instance.respond_to?(:aasm_read_state) || @instance.private_methods.include?('aasm_read_state')
end
end
end

View File

@ -35,7 +35,7 @@ module AASM
base.extend AASM::Persistence::Base::ClassMethods
base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods
base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods)
base.send(:include, AASM::Persistence::ReadState) unless base.method_defined?(:aasm_read_state)
base.send(:include, AASM::Persistence::ReadState)
base.send(:include, AASM::Persistence::ActiveRecordPersistence::WriteState) unless base.method_defined?(:aasm_write_state)
base.send(:include, AASM::Persistence::ActiveRecordPersistence::WriteStateWithoutPersistence) unless base.method_defined?(:aasm_write_state_without_persistence)

View File

@ -37,7 +37,7 @@ module AASM
base.extend AASM::Persistence::Base::ClassMethods
base.extend AASM::Persistence::MongoidPersistence::ClassMethods
base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)
base.send(:include, AASM::Persistence::ReadState) unless base.method_defined?(:aasm_read_state)
base.send(:include, AASM::Persistence::ReadState)
base.send(:include, AASM::Persistence::MongoidPersistence::WriteState) unless base.method_defined?(:aasm_write_state)
base.send(:include, AASM::Persistence::MongoidPersistence::WriteStateWithoutPersistence) unless base.method_defined?(:aasm_write_state_without_persistence)

View File

@ -2,16 +2,17 @@ module AASM
module Persistence
module ReadState
# Returns the value of the aasm_column - called from <tt>aasm_current_state</tt>
# Returns the value of the aasm_column - called from <tt>aasm.current_state</tt>
#
# If it's a new record, and the aasm state column is blank it returns the initial state
# (example provided here for ActiveRecord, but it's true for Mongoid as well):
#
# class Foo < ActiveRecord::Base
# include AASM
# aasm_column :status
# aasm_state :opened
# aasm_state :closed
# aasm :column => :status do
# state :opened
# state :closed
# end
# end
#
# foo = Foo.new

View File

@ -0,0 +1,43 @@
class DefaultState
include AASM
aasm do
state :alpha, :initial => true
state :beta
state :gamma
end
end
class ProvidedState
include AASM
aasm do
state :alpha, :initial => true
state :beta
state :gamma
end
def aasm_read_state
:beta
end
end
class PersistedState < ActiveRecord::Base
include AASM
aasm do
state :alpha, :initial => true
state :beta
state :gamma
end
end
class ProvidedAndPersistedState < ActiveRecord::Base
include AASM
aasm do
state :alpha, :initial => true
state :beta
state :gamma
end
def aasm_read_state
:gamma
end
end

View File

@ -15,10 +15,11 @@ class Gate < ActiveRecord::Base
end
class Reader < ActiveRecord::Base
include AASM
def aasm_read_state
"fi"
end
include AASM
end
class Writer < ActiveRecord::Base

View File

@ -1,6 +1,6 @@
ActiveRecord::Schema.define(:version => 0) do
%w{gates readers writers transients simples simple_new_dsls thieves localizer_test_models}.each do |table_name|
%w{gates readers writers transients simples simple_new_dsls thieves localizer_test_models persisted_states provided_and_persisted_states}.each do |table_name|
create_table table_name, :force => true do |t|
t.string "aasm_state"
end

20
spec/unit/api_spec.rb Normal file
View File

@ -0,0 +1,20 @@
require 'spec_helper'
require 'models/active_record/api.rb'
describe "retrieving the current state" do
it "uses the AASM default" do
DefaultState.new.aasm.current_state.should eql :alpha
end
it "uses the provided method" do
ProvidedState.new.aasm.current_state.should eql :beta
end
it "uses the persistence storage" do
PersistedState.new.aasm.current_state.should eql :alpha
end
it "uses the provided method even if persisted" do
ProvidedAndPersistedState.new.aasm.current_state.should eql :gamma
end
end

View File

@ -24,16 +24,6 @@ describe "class methods for classes without own read or write state" do
end
end
describe "class methods for classes with own read state" do
let(:klass) {Reader}
it_should_behave_like "aasm model"
it "should include all persistence mixins but read state" do
klass.included_modules.should_not be_include(AASM::Persistence::ReadState)
klass.included_modules.should be_include(AASM::Persistence::ActiveRecordPersistence::WriteState)
klass.included_modules.should be_include(AASM::Persistence::ActiveRecordPersistence::WriteStateWithoutPersistence)
end
end
describe "class methods for classes with own write state" do
let(:klass) {Writer}
it_should_behave_like "aasm model"