Skip to content

Commit

Permalink
refactored SupportClasses away
Browse files Browse the repository at this point in the history
  • Loading branch information
alto committed Feb 22, 2013
1 parent 98b54a0 commit d88fa9f
Show file tree
Hide file tree
Showing 17 changed files with 353 additions and 361 deletions.
8 changes: 4 additions & 4 deletions lib/aasm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
require File.join(File.dirname(__FILE__), 'aasm', 'version')
require File.join(File.dirname(__FILE__), 'aasm', 'errors')
require File.join(File.dirname(__FILE__), 'aasm', 'base')
require File.join(File.dirname(__FILE__), 'aasm', 'supporting_classes', 'transition')
require File.join(File.dirname(__FILE__), 'aasm', 'supporting_classes', 'event')
require File.join(File.dirname(__FILE__), 'aasm', 'supporting_classes', 'state')
require File.join(File.dirname(__FILE__), 'aasm', 'supporting_classes', 'localizer')
require File.join(File.dirname(__FILE__), 'aasm', 'transition')
require File.join(File.dirname(__FILE__), 'aasm', 'event')
require File.join(File.dirname(__FILE__), 'aasm', 'state')
require File.join(File.dirname(__FILE__), 'aasm', 'localizer')
require File.join(File.dirname(__FILE__), 'aasm', 'state_machine')
require File.join(File.dirname(__FILE__), 'aasm', 'persistence')
require File.join(File.dirname(__FILE__), 'aasm', 'aasm')
Expand Down
4 changes: 2 additions & 2 deletions lib/aasm/aasm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def aasm_states_for_select

# aasm.event(:event_name).human?
def aasm_human_event_name(event) # event_name?
AASM::SupportingClasses::Localizer.new.human_event_name(self, event)
AASM::Localizer.new.human_event_name(self, event)
end
end # ClassMethods

Expand Down Expand Up @@ -113,7 +113,7 @@ def aasm_events_for_state(state)
end

def aasm_human_state
AASM::SupportingClasses::Localizer.new.human_state_name(self.class, aasm_current_state)
AASM::Localizer.new.human_state_name(self.class, aasm_current_state)
end

private
Expand Down
2 changes: 1 addition & 1 deletion lib/aasm/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def event(name, options={}, &block)
# @clazz.aasm_event(name, options, &block)

unless @state_machine.events.has_key?(name)
@state_machine.events[name] = AASM::SupportingClasses::Event.new(name, options, &block)
@state_machine.events[name] = AASM::Event.new(name, options, &block)
end

# an addition over standard aasm so that, before firing an event, you can ask
Expand Down
125 changes: 125 additions & 0 deletions lib/aasm/event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
module AASM
class Event

attr_reader :name, :options

def initialize(name, options = {}, &block)
@name = name
@transitions = []
update(options, &block)
end

# a neutered version of fire - it doesn't actually fire the event, it just
# executes the transition guards to determine if a transition is even
# an option given current conditions.
def may_fire?(obj, to_state=nil, *args)
_fire(obj, true, to_state, *args) # true indicates test firing
end

def fire(obj, to_state=nil, *args)
_fire(obj, false, to_state, *args) # false indicates this is not a test (fire!)
end

def transitions_from_state?(state)
transitions_from_state(state).any?
end

def transitions_from_state(state)
@transitions.select { |t| t.from == state }
end

def transitions_to_state?(state)
transitions_to_state(state).any?
end

def transitions_to_state(state)
@transitions.select { |t| t.to == state }
end

def all_transitions
@transitions
end

def fire_callbacks(callback_name, record, *args)
invoke_callbacks(@options[callback_name], record, args)
end

def ==(event)
if event.is_a? Symbol
name == event
else
name == event.name
end
end

private

def update(options = {}, &block)
@options = options
if block then
instance_eval(&block)
end
self
end

# Execute if test? == false, otherwise return true/false depending on whether it would fire
def _fire(obj, test, to_state=nil, *args)
if @transitions.map(&:from).any?
transitions = @transitions.select { |t| t.from == obj.aasm_current_state }
return nil if transitions.size == 0
else
transitions = @transitions
end

result = test ? false : nil
transitions.each do |transition|
next if to_state and !Array(transition.to).include?(to_state)
if transition.perform(obj, *args)
if test
result = true
else
result = to_state || Array(transition.to).first
transition.execute(obj, *args)
end

break
end
end
result
end

def invoke_callbacks(code, record, args)
case code
when Symbol, String
record.send(code, *args)
true
when Proc
record.instance_exec(*args, &code)
true
when Array
code.each {|a| invoke_callbacks(a, record, args)}
true
else
false
end
end

## DSL interface
def transitions(trans_opts)
# Create a separate transition for each from state to the given state
Array(trans_opts[:from]).each do |s|
@transitions << AASM::Transition.new(trans_opts.merge({:from => s.to_sym}))
end
# Create a transition if to is specified without from (transitions from ANY state)
@transitions << AASM::Transition.new(trans_opts) if @transitions.empty? && trans_opts[:to]
end

[:after, :before, :error, :success].each do |callback_name|
define_method callback_name do |*args, &block|
options[callback_name] = Array(options[callback_name])
options[callback_name] << block if block
options[callback_name] += Array(args)
end
end
end
end # AASM
54 changes: 54 additions & 0 deletions lib/aasm/localizer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module AASM
class Localizer
def human_event_name(klass, event)
checklist = ancestors_list(klass).inject([]) do |list, ancestor|
list << :"#{i18n_scope(klass)}.events.#{i18n_klass(ancestor)}.#{event}"
list
end
translate_queue(checklist) || I18n.translate(checklist.shift, :default => event.to_s.humanize)
end

def human_state_name(klass, state)
checklist = ancestors_list(klass).inject([]) do |list, ancestor|
list << item_for(klass, state, ancestor)
list << item_for(klass, state, ancestor, :old_style => true)
list
end
translate_queue(checklist) || I18n.translate(checklist.shift, :default => state.to_s.humanize)
end

private

def item_for(klass, state, ancestor, options={})
separator = options[:old_style] ? '.' : '/'
:"#{i18n_scope(klass)}.attributes.#{i18n_klass(ancestor)}.#{klass.aasm_column}#{separator}#{state}"
end

def translate_queue(checklist)
(0...(checklist.size-1)).each do |i|
begin
return I18n.translate(checklist.shift, :raise => true)
rescue I18n::MissingTranslationData
# that's okay
end
end
nil
end

# added for rails 2.x compatibility
def i18n_scope(klass)
klass.respond_to?(:i18n_scope) ? klass.i18n_scope : :activerecord
end

# added for rails < 3.0.3 compatibility
def i18n_klass(klass)
klass.model_name.respond_to?(:i18n_key) ? klass.model_name.i18n_key : klass.name.underscore
end

def ancestors_list(klass)
klass.ancestors.select do |ancestor|
ancestor.respond_to?(:model_name) unless ancestor == ActiveRecord::Base
end
end
end
end # AASM
78 changes: 78 additions & 0 deletions lib/aasm/state.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
module AASM
class State
attr_reader :name, :options

def initialize(name, clazz, options={})
@name = name
@clazz = clazz
update(options)
end

def ==(state)
if state.is_a? Symbol
name == state
else
name == state.name
end
end

def <=>(state)
if state.is_a? Symbol
name <=> state
else
name <=> state.name
end
end

def to_s
name.to_s
end

def fire_callbacks(action, record)
action = @options[action]
catch :halt_aasm_chain do
action.is_a?(Array) ?
action.each {|a| _fire_callbacks(a, record)} :
_fire_callbacks(action, record)
end
end

def display_name
@display_name ||= begin
if Module.const_defined?(:I18n)
localized_name
else
name.to_s.gsub(/_/, ' ').capitalize
end
end
end

def localized_name
AASM::Localizer.new.human_state_name(@clazz, self)
end

def for_select
[display_name, name.to_s]
end

private

def update(options = {})
if options.key?(:display) then
@display_name = options.delete(:display)
end
@options = options
self
end

def _fire_callbacks(action, record)
case action
when Symbol, String
record.send(action)
when Proc
action.call(record)
end
end

end
end # AASM
2 changes: 1 addition & 1 deletion lib/aasm/state_machine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def initialize_copy(orig)
end

def add_state(name, clazz, options)
@states << AASM::SupportingClasses::State.new(name, clazz, options) unless @states.include?(name)
@states << AASM::State.new(name, clazz, options) unless @states.include?(name)
end

end # StateMachine
Expand Down
Loading

0 comments on commit d88fa9f

Please sign in to comment.