Skip to content

Instantly share code, notes, and snippets.

@idrozd
Created July 19, 2013 08:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save idrozd/6037521 to your computer and use it in GitHub Desktop.
Save idrozd/6037521 to your computer and use it in GitHub Desktop.
Ruby Translatable
# Motivation:
# Wanted a more solid way to test validation resulted in correct errors
# other than matching strings;
# Decoupling the very notion of error from message
#
# Sideeffects:
# - Conventional way to namespace error translation by actual path
module Translatable
# this is what all this is about
def to_s
I18n.t i18n_key, {default: default_translation}.merge(i18n_options)
end
# Usage
# SomeTranslatable.new(...).interpolating(bleh: 'huh')
def interpolating additional_options
tap{i18n_options.merge! additional_options}
end
def self.interpolating *args
translatable, additional_options = args
case translatable
when self then translatable.interpolating(additional_options)
else translatable
end
end
def i18n_options
@i18n_options ||= {}
end
def to_s
I18n.t i18n_key, {default: default_translation}.merge(i18n_options)
end
def i18n_key
self.class.name.underscore.gsub(?/,?.)
end
def default_translation
self.class.name.underscore.split(?/).last.gsub(?_,' ')
end
def empty?; false end # for AM::Validations
end
require_relative '../../lib/translatable'
require 'i18n'
require 'active_support/core_ext/string'
describe Translatable do
class YourModel
module Errors
class SomethingIsWrong
include Translatable
end
end
end
subject{YourModel::Errors::SomethingIsWrong.new}
before{I18n.reload!}
its(:to_s){should eq 'something is wrong'}
describe '#interpolating' do
it 'Stores interpolation bits for later use with matching i18n translation' do
I18n.backend.store_translations I18n.locale,
your_model: {errors: {something_is_wrong: 'Very bad %{stuff} happened'}}
expect("#{subject.interpolating(stuff: 'crap')}").to eq \
'Very bad crap happened'
end
end
describe '.interpolating' do
it 'ignores non-translatables' do
regular_error_message = 'Oh damn!'
expect(Translatable.interpolating(regular_error_message,
this_goes_nowhere: 'Uh-oh')).to eq \
'Oh damn!'
end
it 'adds interpolation bits to translatable' do
I18n.backend.store_translations I18n.locale,
your_model: {errors: {something_is_wrong:
'Very bad %{stuff} happened. Probably connected to %{cause}'}}
original_error = subject.interpolating(stuff: 'crap')
error_with_additional_details_added_higher_in_call_stack =
Translatable.interpolating(original_error, cause: 'aliens')
expect("#{error_with_additional_details_added_higher_in_call_stack}").to eq \
'Very bad crap happened. Probably connected to aliens'
end
end
example do
kinda_activemodel_errors = {}
kinda_activemodel_errors['Some attribute'] =
[YourModel::Errors::SomethingIsWrong.new, 'some regular error']
kinda_activemodel_errors['Some attribute'].should \
include(be_a(YourModel::Errors::SomethingIsWrong))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment