Skip to content

Commit

Permalink
using Ruby method resolution to read the current state
Browse files Browse the repository at this point in the history
  • Loading branch information
alto committed Apr 24, 2013
1 parent 7ab505a commit 3a331e8
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 25 deletions.
9 changes: 9 additions & 0 deletions API
@@ -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
5 changes: 5 additions & 0 deletions lib/aasm/aasm.rb
Expand Up @@ -81,6 +81,11 @@ def 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!"
Expand Down
8 changes: 1 addition & 7 deletions lib/aasm/instance_base.rb
Expand Up @@ -6,7 +6,7 @@ def initialize(instance)
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)
Expand Down Expand Up @@ -77,11 +77,5 @@ def set_current_state_with_persistence(state)
save_success
end

private

def persistable?
@instance.respond_to?(:aasm_read_state) || @instance.private_methods.include?('aasm_read_state')
end

end
end
2 changes: 1 addition & 1 deletion lib/aasm/persistence/active_record_persistence.rb
Expand Up @@ -35,7 +35,7 @@ def self.included(base)
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)

Expand Down
2 changes: 1 addition & 1 deletion lib/aasm/persistence/mongoid_persistence.rb
Expand Up @@ -37,7 +37,7 @@ def self.included(base)
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)

Expand Down
9 changes: 5 additions & 4 deletions lib/aasm/persistence/read_state.rb
Expand Up @@ -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
Expand Down
43 changes: 43 additions & 0 deletions spec/models/active_record/api.rb
@@ -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
3 changes: 2 additions & 1 deletion spec/models/persistence.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion spec/schema.rb
@@ -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
Expand Down
20 changes: 20 additions & 0 deletions spec/unit/api_spec.rb
@@ -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
10 changes: 0 additions & 10 deletions spec/unit/persistence/active_record_persistence_spec.rb
Expand Up @@ -24,16 +24,6 @@
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"
Expand Down

0 comments on commit 3a331e8

Please sign in to comment.