Skip to content

Commit

Permalink
Merge pull request aasm#28 from etehtsea/i18n
Browse files Browse the repository at this point in the history
I18n support
  • Loading branch information
alto committed Sep 2, 2011
2 parents df86a85 + 8e7921c commit d92a679
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 2 deletions.
1 change: 1 addition & 0 deletions lib/aasm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ module AASM
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')
require File.join(File.dirname(__FILE__), 'aasm', 'i18n')
12 changes: 10 additions & 2 deletions lib/aasm/aasm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class UndefinedState < RuntimeError

def self.included(base) #:nodoc:
base.extend AASM::ClassMethods

AASM::Persistence.set_persistence(base)
unless AASM::StateMachine[base]
AASM::StateMachine[base] = AASM::StateMachine.new('')
Expand Down Expand Up @@ -41,7 +42,7 @@ def aasm_state(name, options={})
aasm_current_state == name
end
end

def aasm_event(name, options = {}, &block)
sm = AASM::StateMachine[self]

Expand Down Expand Up @@ -70,8 +71,11 @@ def aasm_states_for_select
AASM::StateMachine[self].states.map { |state| state.for_select }
end

def human_event_name(event)
AASM::I18n.new.human_event_name(self, event)
end
end

# Instance methods
def aasm_current_state
return @aasm_current_state if @aasm_current_state
Expand Down Expand Up @@ -105,6 +109,10 @@ def aasm_events_for_state(state)
events.map {|event| event.name}
end

def human_state
AASM::I18n.new.human_state(self)
end

private

def set_aasm_current_state_with_persistence(state)
Expand Down
36 changes: 36 additions & 0 deletions lib/aasm/i18n.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
class AASM::I18n
def human_event_name(klass, event)
defaults = ancestors_list(klass).map do |ancestor|
:"#{i18n_scope(klass)}.events.#{i18n_klass(ancestor)}.#{event}"
end << event.to_s.humanize

I18n.translate(defaults.shift, :default => defaults, :raise => true)
end

def human_state(obj)
klass = obj.class
defaults = ancestors_list(klass).map do |ancestor|
:"#{i18n_scope(klass)}.attributes.#{i18n_klass(ancestor)}.#{klass.aasm_column}.#{obj.aasm_current_state}"
end << obj.aasm_current_state.to_s.humanize

I18n.translate(defaults.shift, :default => defaults, :raise => true)
end

private

# 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
10 changes: 10 additions & 0 deletions spec/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
en:
activerecord:
events:
i18n_test_model:
close: "Let's close it!"

attributes:
i18n_test_model:
aasm_state:
open: "It's opened now!"
59 changes: 59 additions & 0 deletions spec/unit/i18n_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require 'spec_helper'
require 'active_record'
require 'logger'
require 'i18n'

ActiveRecord::Base.logger = Logger.new(STDERR)

class Connection
end

class I18nTestModel < ActiveRecord::Base
include AASM

attr_accessor :aasm_state

aasm_initial_state :open
aasm_state :opened
aasm_state :closed

aasm_event :close
aasm_event :open
end

describe AASM::I18n do
before(:all) do
I18n.load_path << 'spec/en.yml'
I18n.default_locale = :en
end

after(:all) { I18n.load_path.clear }

before do
connection = mock(Connection, :columns => [])
I18nTestModel.stub!(:connection).and_return(connection)
end

let (:foo_opened) { I18nTestModel.new }
let (:foo_closed) { I18nTestModel.new.tap { |x| x.aasm_state = :closed } }

context '.human_state' do
it 'should return translated state value' do
foo_opened.human_state.should == "It's opened now!"
end

it 'should return humanized value if not localized' do
foo_closed.human_state.should == "Closed"
end
end

context '.human_event_name' do
it 'should return translated event name' do
I18nTestModel.human_event_name(:close).should == "Let's close it!"
end

it 'should return humanized event name' do
I18nTestModel.human_event_name(:open).should == "Open"
end
end
end

0 comments on commit d92a679

Please sign in to comment.