From bbafd22c67d1ca721029d095ac7c1475d2f2d63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Bo=CC=88ttger?= Date: Wed, 24 Apr 2013 14:19:02 +0200 Subject: [PATCH] no need for WriteStateWithoutPersistence mixin anymore (to keep adding persistence simple) --- API | 19 +++++++++- lib/aasm/aasm.rb | 5 +++ lib/aasm/instance_base.rb | 4 +- .../persistence/active_record_persistence.rb | 38 ++++++++----------- lib/aasm/persistence/mongoid_persistence.rb | 38 ++++++++----------- spec/models/active_record/api.rb | 16 ++++++-- spec/unit/api_spec.rb | 34 +++++++++++++++-- .../active_record_persistence_spec.rb | 24 ------------ 8 files changed, 97 insertions(+), 81 deletions(-) diff --git a/API b/API index b9acad1..275a57d 100644 --- a/API +++ b/API @@ -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 include AASM @@ -8,12 +10,25 @@ Overwrite method to read the current state 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 include AASM 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 end end diff --git a/lib/aasm/aasm.rb b/lib/aasm/aasm.rb index b8d8d62..7f6a9ca 100644 --- a/lib/aasm/aasm.rb +++ b/lib/aasm/aasm.rb @@ -91,6 +91,11 @@ module AASM true end + # may be overwritten by persistence mixins + def aasm_write_state_without_persistence(new_state) + true + 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!" diff --git a/lib/aasm/instance_base.rb b/lib/aasm/instance_base.rb index e79352a..d016cbb 100644 --- a/lib/aasm/instance_base.rb +++ b/lib/aasm/instance_base.rb @@ -10,9 +10,7 @@ module AASM end 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) - end + @instance.aasm_write_state_without_persistence(state) @current_state = state end diff --git a/lib/aasm/persistence/active_record_persistence.rb b/lib/aasm/persistence/active_record_persistence.rb index 077f449..3eae3b3 100644 --- a/lib/aasm/persistence/active_record_persistence.rb +++ b/lib/aasm/persistence/active_record_persistence.rb @@ -6,9 +6,6 @@ module AASM # * extends the model with ClassMethods # * includes InstanceMethods # - # Unless the corresponding methods are already defined, it includes - # * WriteStateWithoutPersistence - # # Adds # # before_validation :aasm_ensure_initial_state, :on => :create @@ -33,7 +30,6 @@ module AASM base.send(:include, AASM::Persistence::Base) base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods 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 base.before_validation(:aasm_ensure_initial_state, :on => :create) @@ -98,6 +94,22 @@ module AASM true end + # Writes state 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 # Ensures that if the aasm_state column is nil and the record is new @@ -126,24 +138,6 @@ module AASM end end # InstanceMethods - module WriteStateWithoutPersistence - # Writes state 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 diff --git a/lib/aasm/persistence/mongoid_persistence.rb b/lib/aasm/persistence/mongoid_persistence.rb index a6ae33e..082f112 100644 --- a/lib/aasm/persistence/mongoid_persistence.rb +++ b/lib/aasm/persistence/mongoid_persistence.rb @@ -6,9 +6,6 @@ module AASM # * extends the model with ClassMethods # * includes InstanceMethods # - # Unless the corresponding methods are already defined, it includes - # * WriteStateWithoutPersistence - # # Adds # # before_validation :aasm_ensure_initial_state @@ -35,7 +32,6 @@ module AASM base.send(:include, AASM::Persistence::Base) base.extend AASM::Persistence::MongoidPersistence::ClassMethods 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. # base.before_validation_on_create :aasm_ensure_initial_state @@ -88,6 +84,22 @@ module AASM true end + # Writes state 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 # Ensures that if the aasm_state column is nil and the record is new @@ -110,24 +122,6 @@ module AASM end end # InstanceMethods - module WriteStateWithoutPersistence - # Writes state 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 def aasm_state_with_named_scope name, options = {} aasm_state_without_named_scope name, options diff --git a/spec/models/active_record/api.rb b/spec/models/active_record/api.rb index 082e9ea..d6c33da 100644 --- a/spec/models/active_record/api.rb +++ b/spec/models/active_record/api.rb @@ -1,5 +1,5 @@ class DefaultState - attr_accessor :transient_store + attr_accessor :transient_store, :persisted_store include AASM aasm do state :alpha, :initial => true @@ -12,7 +12,7 @@ class DefaultState end class ProvidedState - attr_accessor :transient_store + attr_accessor :transient_store, :persisted_store include AASM aasm do state :alpha, :initial => true @@ -28,12 +28,16 @@ class ProvidedState end def aasm_write_state(new_state) + @persisted_store = new_state + end + + def aasm_write_state_without_persistence(new_state) @transient_store = new_state end end class PersistedState < ActiveRecord::Base - attr_accessor :transient_store + attr_accessor :transient_store, :persisted_store include AASM aasm do state :alpha, :initial => true @@ -46,7 +50,7 @@ class PersistedState < ActiveRecord::Base end class ProvidedAndPersistedState < ActiveRecord::Base - attr_accessor :transient_store + attr_accessor :transient_store, :persisted_store include AASM aasm do state :alpha, :initial => true @@ -62,6 +66,10 @@ class ProvidedAndPersistedState < ActiveRecord::Base end def aasm_write_state(new_state) + @persisted_store = new_state + end + + def aasm_write_state_without_persistence(new_state) @transient_store = new_state end end diff --git a/spec/unit/api_spec.rb b/spec/unit/api_spec.rb index 55a08d9..6ab736b 100644 --- a/spec/unit/api_spec.rb +++ b/spec/unit/api_spec.rb @@ -19,28 +19,54 @@ describe "reading the current state" do end end -describe "writing the current state" do +describe "writing and persisting the current state" do it "uses the AASM default" do o = DefaultState.new o.release! - o.transient_store.should be_nil + o.persisted_store.should be_nil end it "uses the provided method" do o = ProvidedState.new o.release! - o.transient_store.should eql :beta + o.persisted_store.should eql :beta end it "uses the persistence storage" do o = PersistedState.new o.release! - o.transient_store.should be_nil + o.persisted_store.should be_nil end it "uses the provided method even if persisted" do o = ProvidedAndPersistedState.new 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 end end diff --git a/spec/unit/persistence/active_record_persistence_spec.rb b/spec/unit/persistence/active_record_persistence_spec.rb index 9d73811..fb2ebb5 100644 --- a/spec/unit/persistence/active_record_persistence_spec.rb +++ b/spec/unit/persistence/active_record_persistence_spec.rb @@ -14,30 +14,6 @@ shared_examples_for "aasm model" do 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 let(:gate) {Gate.new}