diff --git a/CHANGELOG.md b/CHANGELOG.md index a2bb8b1..e1b7789 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 3.0.15 + + * added support for localized state names (on a class level, like Record.aasm.states.map(&:localized_name)) + ## 3.0.14 * supporting event inspection for to-states transitions (`Event#transitions_to_state?`) diff --git a/lib/aasm/aasm.rb b/lib/aasm/aasm.rb index 5b17fdf..8ce5bf8 100644 --- a/lib/aasm/aasm.rb +++ b/lib/aasm/aasm.rb @@ -111,7 +111,7 @@ module AASM end def aasm_human_state - AASM::SupportingClasses::Localizer.new.human_state(self) + AASM::SupportingClasses::Localizer.new.human_state_name(self.class, aasm_current_state) end private diff --git a/lib/aasm/base.rb b/lib/aasm/base.rb index 209fcf3..7ef0f4f 100644 --- a/lib/aasm/base.rb +++ b/lib/aasm/base.rb @@ -26,7 +26,7 @@ module AASM def state(name, options={}) # @clazz.aasm_state(name, options) sm = AASM::StateMachine[@clazz] - sm.create_state(name, options) + sm.create_state(name, @clazz, options) sm.initial_state = name if options[:initial] || !sm.initial_state @clazz.send(:define_method, "#{name.to_s}?") do diff --git a/lib/aasm/state_machine.rb b/lib/aasm/state_machine.rb index 18531e0..64a3123 100644 --- a/lib/aasm/state_machine.rb +++ b/lib/aasm/state_machine.rb @@ -29,8 +29,8 @@ module AASM @events = @events.dup end - def create_state(name, options) - @states << AASM::SupportingClasses::State.new(name, options) unless @states.include?(name) + def create_state(name, clazz, options) + @states << AASM::SupportingClasses::State.new(name, clazz, options) unless @states.include?(name) end end # StateMachine diff --git a/lib/aasm/supporting_classes/localizer.rb b/lib/aasm/supporting_classes/localizer.rb index fe90510..85b0673 100644 --- a/lib/aasm/supporting_classes/localizer.rb +++ b/lib/aasm/supporting_classes/localizer.rb @@ -9,21 +9,20 @@ module AASM translate_queue(checklist) || I18n.translate(checklist.shift, :default => event.to_s.humanize) end - def human_state(obj) - klass = obj.class + def human_state_name(klass, state) checklist = ancestors_list(klass).inject([]) do |list, ancestor| - list << item_for(obj, klass, ancestor) - list << item_for(obj, klass, ancestor, :old_style => true) + 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 => obj.aasm_current_state.to_s.humanize) + translate_queue(checklist) || I18n.translate(checklist.shift, :default => state.to_s.humanize) end private - def item_for(obj, klass, ancestor, options={}) + def item_for(klass, state, ancestor, options={}) separator = options[:old_style] ? '.' : '/' - :"#{i18n_scope(klass)}.attributes.#{i18n_klass(ancestor)}.#{klass.aasm_column}#{separator}#{obj.aasm_current_state}" + :"#{i18n_scope(klass)}.attributes.#{i18n_klass(ancestor)}.#{klass.aasm_column}#{separator}#{state}" end def translate_queue(checklist) diff --git a/lib/aasm/supporting_classes/state.rb b/lib/aasm/supporting_classes/state.rb index ed7e5ab..6df5431 100644 --- a/lib/aasm/supporting_classes/state.rb +++ b/lib/aasm/supporting_classes/state.rb @@ -3,8 +3,9 @@ module AASM class State attr_reader :name, :options - def initialize(name, options={}) + def initialize(name, clazz, options={}) @name = name + @clazz = clazz update(options) end @@ -24,6 +25,10 @@ module AASM end end + def to_s + name.to_s + end + def fire_callbacks(action, record) action = @options[action] catch :halt_aasm_chain do @@ -34,7 +39,17 @@ module AASM end def display_name - @display_name ||= name.to_s.gsub(/_/, ' ').capitalize + @display_name ||= begin + if Module.const_defined?(:I18n) + localized_name + else + name.to_s.gsub(/_/, ' ').capitalize + end + end + end + + def localized_name + AASM::SupportingClasses::Localizer.new.human_state_name(@clazz, self) end def for_select diff --git a/spec/en.yml b/spec/en.yml index 31d10b6..458ebb0 100644 --- a/spec/en.yml +++ b/spec/en.yml @@ -6,4 +6,4 @@ en: attributes: localizer_test_model: - aasm_state/open: "It's opened now!" + aasm_state/opened: "It's open now!" diff --git a/spec/en_deprecated_style.yml b/spec/en_deprecated_style.yml index 38ab0bb..b02e998 100644 --- a/spec/en_deprecated_style.yml +++ b/spec/en_deprecated_style.yml @@ -7,4 +7,4 @@ en: attributes: localizer_test_model: aasm_state: - open: "It's opened now!" + opened: "It's open now!" diff --git a/spec/unit/supporting_classes/localizer_spec.rb b/spec/unit/supporting_classes/localizer_spec.rb index 673f31b..6c7f2a5 100644 --- a/spec/unit/supporting_classes/localizer_spec.rb +++ b/spec/unit/supporting_classes/localizer_spec.rb @@ -10,7 +10,7 @@ class LocalizerTestModel < ActiveRecord::Base attr_accessor :aasm_state - aasm_initial_state :open + aasm_initial_state :opened aasm_state :opened aasm_state :closed @@ -18,6 +18,26 @@ class LocalizerTestModel < ActiveRecord::Base aasm_event :open end +describe 'localized state names' do + before(:all) do + I18n.load_path << 'spec/en.yml' + I18n.default_locale = :en + I18n.reload! + end + + after(:all) do + I18n.load_path.clear + end + + it 'should localize' do + LocalizerTestModel.aasm.states.detect {|s| s == :opened}.localized_name.should == "It's open now!" + end + + it 'should use fallback' do + LocalizerTestModel.aasm.states.detect {|s| s == :closed}.localized_name.should == 'Closed' + end +end + describe AASM::SupportingClasses::Localizer, "new style" do before(:all) do I18n.load_path << 'spec/en.yml' @@ -34,7 +54,7 @@ describe AASM::SupportingClasses::Localizer, "new style" do context 'aasm_human_state' do it 'should return translated state value' do - foo_opened.aasm_human_state.should == "It's opened now!" + foo_opened.aasm_human_state.should == "It's open now!" end it 'should return humanized value if not localized' do @@ -69,7 +89,7 @@ describe AASM::SupportingClasses::Localizer, "deprecated style" do context 'aasm_human_state' do it 'should return translated state value' do - foo_opened.aasm_human_state.should == "It's opened now!" + foo_opened.aasm_human_state.should == "It's open now!" end it 'should return humanized value if not localized' do diff --git a/spec/unit/supporting_classes/state_spec.rb b/spec/unit/supporting_classes/state_spec.rb index 5c83908..6c4a3e0 100644 --- a/spec/unit/supporting_classes/state_spec.rb +++ b/spec/unit/supporting_classes/state_spec.rb @@ -7,7 +7,7 @@ describe AASM::SupportingClasses::State do end def new_state(options={}) - AASM::SupportingClasses::State.new(@name, @options.merge(options)) + AASM::SupportingClasses::State.new(@name, Conversation, @options.merge(options)) end it 'should set the name' do