no need for WriteStateWithoutPersistence mixin anymore (to keep adding persistence simple)

This commit is contained in:
Thorsten Böttger 2013-04-24 14:19:02 +02:00
parent 95ef7fc834
commit bbafd22c67
8 changed files with 97 additions and 81 deletions

19
API
View File

@ -1,4 +1,6 @@
Overwrite method to read the current state
Overwrite method to read the current state. Used to provide another storage mechanism,
different from the standard Rails read_attribute method.
class MyClass class MyClass
include AASM include AASM
@ -8,12 +10,25 @@ Overwrite method to read the current state
end end
end end
Overwrite method to write the current state
Overwrite method to write the current state (and actually persist it). Used to provide
another storage mechanism, different from the standard Rails write_attribute method.
class MyClass class MyClass
include AASM include AASM
def aasm_write_state def aasm_write_state
# store and persist the current state manually
end
end
Overwrite method to write the current state (without persisting it).
class MyClass
include AASM
def aasm_write_state_without_persistence
# store the current state manually # store the current state manually
end end
end end

View File

@ -91,6 +91,11 @@ module AASM
true true
end end
# may be overwritten by persistence mixins
def aasm_write_state_without_persistence(new_state)
true
end
# deprecated # deprecated
def aasm_current_state def aasm_current_state
# warn "#aasm_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.state instead!" # warn "#aasm_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.state instead!"

View File

@ -10,9 +10,7 @@ module AASM
end end
def current_state=(state) def current_state=(state)
if @instance.respond_to?(:aasm_write_state_without_persistence) || @instance.private_methods.include?('aasm_write_state_without_persistence') @instance.aasm_write_state_without_persistence(state)
@instance.aasm_write_state_without_persistence(state)
end
@current_state = state @current_state = state
end end

View File

@ -6,9 +6,6 @@ module AASM
# * extends the model with ClassMethods # * extends the model with ClassMethods
# * includes InstanceMethods # * includes InstanceMethods
# #
# Unless the corresponding methods are already defined, it includes
# * WriteStateWithoutPersistence
#
# Adds # Adds
# #
# before_validation :aasm_ensure_initial_state, :on => :create # before_validation :aasm_ensure_initial_state, :on => :create
@ -33,7 +30,6 @@ module AASM
base.send(:include, AASM::Persistence::Base) base.send(:include, AASM::Persistence::Base)
base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods
base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods) base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods)
base.send(:include, AASM::Persistence::ActiveRecordPersistence::WriteStateWithoutPersistence) unless base.method_defined?(:aasm_write_state_without_persistence)
if ActiveRecord::VERSION::MAJOR >= 3 if ActiveRecord::VERSION::MAJOR >= 3
base.before_validation(:aasm_ensure_initial_state, :on => :create) base.before_validation(:aasm_ensure_initial_state, :on => :create)
@ -98,6 +94,22 @@ module AASM
true true
end end
# Writes <tt>state</tt> to the state column, but does not persist it to the database
#
# foo = Foo.find(1)
# foo.aasm_current_state # => :opened
# foo.close
# foo.aasm_current_state # => :closed
# Foo.find(1).aasm_current_state # => :opened
# foo.save
# foo.aasm_current_state # => :closed
# Foo.find(1).aasm_current_state # => :closed
#
# NOTE: intended to be called from an event
def aasm_write_state_without_persistence(state)
write_attribute(self.class.aasm_column, state.to_s)
end
private private
# Ensures that if the aasm_state column is nil and the record is new # Ensures that if the aasm_state column is nil and the record is new
@ -126,24 +138,6 @@ module AASM
end end
end # InstanceMethods end # InstanceMethods
module WriteStateWithoutPersistence
# Writes <tt>state</tt> to the state column, but does not persist it to the database
#
# foo = Foo.find(1)
# foo.aasm_current_state # => :opened
# foo.close
# foo.aasm_current_state # => :closed
# Foo.find(1).aasm_current_state # => :opened
# foo.save
# foo.aasm_current_state # => :closed
# Foo.find(1).aasm_current_state # => :closed
#
# NOTE: intended to be called from an event
def aasm_write_state_without_persistence(state)
write_attribute(self.class.aasm_column, state.to_s)
end
end
end end
end end
end end

View File

@ -6,9 +6,6 @@ module AASM
# * extends the model with ClassMethods # * extends the model with ClassMethods
# * includes InstanceMethods # * includes InstanceMethods
# #
# Unless the corresponding methods are already defined, it includes
# * WriteStateWithoutPersistence
#
# Adds # Adds
# #
# before_validation :aasm_ensure_initial_state # before_validation :aasm_ensure_initial_state
@ -35,7 +32,6 @@ module AASM
base.send(:include, AASM::Persistence::Base) base.send(:include, AASM::Persistence::Base)
base.extend AASM::Persistence::MongoidPersistence::ClassMethods base.extend AASM::Persistence::MongoidPersistence::ClassMethods
base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods) base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)
base.send(:include, AASM::Persistence::MongoidPersistence::WriteStateWithoutPersistence) unless base.method_defined?(:aasm_write_state_without_persistence)
# Mongoid's Validatable gem dependency goes not have a before_validation_on_xxx hook yet. # Mongoid's Validatable gem dependency goes not have a before_validation_on_xxx hook yet.
# base.before_validation_on_create :aasm_ensure_initial_state # base.before_validation_on_create :aasm_ensure_initial_state
@ -88,6 +84,22 @@ module AASM
true true
end end
# Writes <tt>state</tt> to the state column, but does not persist it to the database
#
# foo = Foo.find(1)
# foo.aasm_current_state # => :opened
# foo.close
# foo.aasm_current_state # => :closed
# Foo.find(1).aasm_current_state # => :opened
# foo.save
# foo.aasm_current_state # => :closed
# Foo.find(1).aasm_current_state # => :closed
#
# NOTE: intended to be called from an event
def aasm_write_state_without_persistence(state)
write_attribute(self.class.aasm_column, state.to_s)
end
private private
# Ensures that if the aasm_state column is nil and the record is new # Ensures that if the aasm_state column is nil and the record is new
@ -110,24 +122,6 @@ module AASM
end end
end # InstanceMethods end # InstanceMethods
module WriteStateWithoutPersistence
# Writes <tt>state</tt> to the state column, but does not persist it to the database
#
# foo = Foo.find(1)
# foo.aasm_current_state # => :opened
# foo.close
# foo.aasm_current_state # => :closed
# Foo.find(1).aasm_current_state # => :opened
# foo.save
# foo.aasm_current_state # => :closed
# Foo.find(1).aasm_current_state # => :closed
#
# NOTE: intended to be called from an event
def aasm_write_state_without_persistence(state)
write_attribute(self.class.aasm_column, state.to_s)
end
end
module NamedScopeMethods module NamedScopeMethods
def aasm_state_with_named_scope name, options = {} def aasm_state_with_named_scope name, options = {}
aasm_state_without_named_scope name, options aasm_state_without_named_scope name, options

View File

@ -1,5 +1,5 @@
class DefaultState class DefaultState
attr_accessor :transient_store attr_accessor :transient_store, :persisted_store
include AASM include AASM
aasm do aasm do
state :alpha, :initial => true state :alpha, :initial => true
@ -12,7 +12,7 @@ class DefaultState
end end
class ProvidedState class ProvidedState
attr_accessor :transient_store attr_accessor :transient_store, :persisted_store
include AASM include AASM
aasm do aasm do
state :alpha, :initial => true state :alpha, :initial => true
@ -28,12 +28,16 @@ class ProvidedState
end end
def aasm_write_state(new_state) def aasm_write_state(new_state)
@persisted_store = new_state
end
def aasm_write_state_without_persistence(new_state)
@transient_store = new_state @transient_store = new_state
end end
end end
class PersistedState < ActiveRecord::Base class PersistedState < ActiveRecord::Base
attr_accessor :transient_store attr_accessor :transient_store, :persisted_store
include AASM include AASM
aasm do aasm do
state :alpha, :initial => true state :alpha, :initial => true
@ -46,7 +50,7 @@ class PersistedState < ActiveRecord::Base
end end
class ProvidedAndPersistedState < ActiveRecord::Base class ProvidedAndPersistedState < ActiveRecord::Base
attr_accessor :transient_store attr_accessor :transient_store, :persisted_store
include AASM include AASM
aasm do aasm do
state :alpha, :initial => true state :alpha, :initial => true
@ -62,6 +66,10 @@ class ProvidedAndPersistedState < ActiveRecord::Base
end end
def aasm_write_state(new_state) def aasm_write_state(new_state)
@persisted_store = new_state
end
def aasm_write_state_without_persistence(new_state)
@transient_store = new_state @transient_store = new_state
end end
end end

View File

@ -19,28 +19,54 @@ describe "reading the current state" do
end end
end end
describe "writing the current state" do describe "writing and persisting the current state" do
it "uses the AASM default" do it "uses the AASM default" do
o = DefaultState.new o = DefaultState.new
o.release! o.release!
o.transient_store.should be_nil o.persisted_store.should be_nil
end end
it "uses the provided method" do it "uses the provided method" do
o = ProvidedState.new o = ProvidedState.new
o.release! o.release!
o.transient_store.should eql :beta o.persisted_store.should eql :beta
end end
it "uses the persistence storage" do it "uses the persistence storage" do
o = PersistedState.new o = PersistedState.new
o.release! o.release!
o.transient_store.should be_nil o.persisted_store.should be_nil
end end
it "uses the provided method even if persisted" do it "uses the provided method even if persisted" do
o = ProvidedAndPersistedState.new o = ProvidedAndPersistedState.new
o.release! o.release!
o.persisted_store.should eql :beta
end
end
describe "writing the current state without persisting it" do
it "uses the AASM default" do
o = DefaultState.new
o.release
o.transient_store.should be_nil
end
it "uses the provided method" do
o = ProvidedState.new
o.release
o.transient_store.should eql :beta
end
it "uses the persistence storage" do
o = PersistedState.new
o.release
o.transient_store.should be_nil
end
it "uses the provided method even if persisted" do
o = ProvidedAndPersistedState.new
o.release
o.transient_store.should eql :beta o.transient_store.should eql :beta
end end
end end

View File

@ -14,30 +14,6 @@ shared_examples_for "aasm model" do
end end
end end
describe "class methods for classes without own read or write state" do
let(:klass) {Gate}
it_should_behave_like "aasm model"
it "should include all persistence mixins" do
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"
it "should include include all persistence mixins but write state" do
klass.included_modules.should be_include(AASM::Persistence::ActiveRecordPersistence::WriteStateWithoutPersistence)
end
end
describe "class methods for classes without persistence" do
let(:klass) {Transient}
it_should_behave_like "aasm model"
it "should include all mixins but persistence" do
klass.included_modules.should_not be_include(AASM::Persistence::ActiveRecordPersistence::WriteStateWithoutPersistence)
end
end
describe "instance methods" do describe "instance methods" do
let(:gate) {Gate.new} let(:gate) {Gate.new}