Allow duplicate state names in subclasses

When an AASM including class is subclassed, a shallow copy is made of
the StateMachine object.  This means that all subclasses share the same
states hash and thus the same set of states, which prevents (among other
things) different subclasses from using the same state names.

Give StateMachine a smart #clone method that copies the states hash and
invoke that rather than #dup upon subclassing.
This commit is contained in:
Tim Pope 2008-11-05 11:06:36 -05:00
parent fee9487e0d
commit d59dbbf6b0
3 changed files with 22 additions and 7 deletions

View File

@ -22,7 +22,7 @@ module AASM
module ClassMethods
def inherited(klass)
AASM::StateMachine[klass] = AASM::StateMachine[self].dup
AASM::StateMachine[klass] = AASM::StateMachine[self].clone
super
end

View File

@ -22,6 +22,12 @@ module AASM
@config = OpenStruct.new
end
def clone
klone = super
klone.states = states.clone
klone
end
def create_state(name, options)
@states << AASM::SupportingClasses::State.new(name, options) unless @states.include?(name)
end

View File

@ -70,12 +70,21 @@ describe AASM, '- class level definitions' do
end
describe AASM, '- when included' do
it 'should invoke the original inherited callback when subclassed' do
parent = Class.new
parent.should_receive(:inherited)
parent.send(:include, AASM)
child = Class.new(parent)
describe AASM, '- subclassing' do
before(:each) do
@parent = Class.new do
include AASM
end
end
it 'should invoke the original inherited callback' do
@parent.should_receive(:inherited)
Class.new(@parent)
end
it 'should have a unique states hash' do
child = Class.new(@parent)
child.aasm_states.equal?(@parent.aasm_states).should be_false
end
end