I have the following I18n-Setup
config.i18n.available_locales = [:de, :en]
config.i18n.fallbacks = true
config.i18n.enforce_available_locales = true
config.i18n.default_locale = :de
I have a URL-based locale-switch:
# routes.rb
scope '(:locale)/', locale: /en|de/, defaults: {locale: 'de'} do
resources :programmes
root 'programmes#portal'
end
In my ApplicationController I set the locale as a before_filter
# application_controller.rb
before_filter :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
In my application.rb
config.i18n.available_locales = [:de, :en]
config.i18n.fallbacks = true
config.i18n.enforce_available_locales = true
config.i18n.default_locale = :de
I have a fallback for both of my languages (/app/initializers/globalize.rb):
Globalize.fallbacks = {:en => [:en, :de], :de => [:de, :en]}
My development.rb and production.rb don't differ in terms of I18n setup.
Now I run into the following problem:
I have a record which is only tranlsated in EN
In my development environment using locale = DE the fallback to the english title works
However, in production environment this fallback does not work.
It is not clear to my why this does not work in production environment.
Update: In the production console on my production environment the fallback seems to work as well:
irb(main):005:0* I18n.locale
=> :de
irb(main):006:0> p=Programme.find(1289)
=> #<Programme id: 1289, created_at: "2014-07-08 09:58:21", ....>
irb(main):007:0> p.title
=> "English Title"
irb(main):008:0> I18n.locale = :en
=> :en
irb(main):009:0> p.title
=> "English Title"
irb(main):010:0> I18n.locale = :something-undefined
=> :something-undefined
irb(main):011:0> p.title
=> nil
irb(main):012:0> I18n.default_locale
=> :de
TL;DR
# config/application.rb
require 'i18n/backend/fallbacks'
Answer
I recently had a similar error in development environment.
Here it is my relevant code setup:
# Gemfile
gem 'globalize', '5.0.1'
gem 'rails', '4.2.2'
gem 'rails-i18n', '4.0.4'
and:
# config/application.rb
config.i18n.available_locales = [:it, :en]
config.i18n.enforce_available_locales = true
config.i18n.default_locale = :it
config.i18n.fallbacks = true
With this setup i got these results:
2.2.2 :001 > Product.find_by_name('Fun Farm').translations.inspect
=> "#<ActiveRecord::Associations::CollectionProxy [#<Product::Translation id: 16, product_id: 16, locale: \"it\", created_at: \"2015-06-20 08:33:51\", updated_at: \"2015-06-20 08:33:51\", awards: \"Vincitore della <strong>Ludoteca Ideale</strong>, ...\", spot: \"Il party game per chi ha i riflessi pronti.\", synopsis: \"<p>\\n Gli animali stanno scappando dalla fattoria ...\">]>"
2.2.2 :002 > Product.find_by_name('Fun Farm').spot
=> "Il party game per chi ha i riflessi pronti."
2.2.2 :003 > I18n::locale = :en
=> :en
2.2.2 :004 > Product.find_by_name('Fun Farm').spot
=> nil
Adding:
# config/application.rb
require 'i18n/backend/fallbacks'
it works:
2.2.2 :001 > Product.find_by_name('Fun Farm').translations.inspect
=> "#<ActiveRecord::Associations::CollectionProxy [#<Product::Translation id: 16, product_id: 16, locale: \"it\", created_at: \"2015-06-20 08:33:51\", updated_at: \"2015-06-20 08:33:51\", awards: \"Vincitore della <strong>Ludoteca Ideale</strong>, ...\", spot: \"Il party game per chi ha i riflessi pronti.\", synopsis: \"<p>\\n Gli animali stanno scappando dalla fattoria ...\">]>"
2.2.2 :002 > Product.find_by_name('Fun Farm').spot
=> "Il party game per chi ha i riflessi pronti."
2.2.2 :003 > I18n::locale = :en
=> :en
2.2.2 :004 > Product.find_by_name('Fun Farm').spot
=> "Il party game per chi ha i riflessi pronti."
Related
We use the globalize gem and have included Rails.application.config.i18n.fallbacks = [:en] in config/initializers/i18n.rb so that the user sees the English translation of a field if one does not exist in their own language.
That means we see this behavior, as expected:
class Post < ActiveRecord::Base
translates :title, :name
end
puts post.translations.inspect
# => [#<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
#<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>]
I18n.locale = :en
post.title # => 'Globalize rocks!'
post.name # => 'Globalize'
I18n.locale = :nl
post.title # => ''
post.name # => 'Globalize'
In just one place where we are displaying "posts", the client asked us to not show anything if there is no translation for the "name". Is there a built in way to do this? I.e.:
I18n.locale = :nl
post.title # => ''
post.name_if_translated # => nil
I did find one workaround:
post.name_translations[I18n.locale]
But maybe there's a better way?
I've got this behaviour that I can't explain:
$ rails console
Loading development environment (Rails 4.2.7.1)
irb(main):001:0> I18n.locale
=> :"en-GB"
irb(main):002:0> I18n.available_locales
=> [:en, :"en-GB"]
irb(main):003:0> 'bear'.pluralize
=> "bears"
irb(main):004:0> 'bear'.pluralize(2, :"en-GB")
=> "bear" # <- sadness here
irb(main):005:0> 'bear'.pluralize(2, :en)
=> "bears"
irb(main):006:0> I18n.translate("gst")
=> "VAT" # <- correct translation from 'config/locales/en-GB.yml'
irb(main):007:0> ActiveSupport::Inflector.pluralize('bear', :en)
=> "bears"
irb(main):008:0> ActiveSupport::Inflector.pluralize('bear', :'en-GB')
=> "bear"
My <rails_root>/uk/config/locales/en-GB.yml:
en-GB:
gst: VAT
How come the regionalised locale is available, in use, and works well with translations but not with pluralisation? Just in case, I've put
config.i18n.fallbacks = { :'en-GB' => :en } in my config/application.rb, but without effect. I've got no clue on where I should investigate further...
Any ideas?
Thank you.
Ok, this has been fixed in Rails 5 thanks to this patch
How do I access translation for nil value?
I tried with this locale(yml file):
pt-BR:
boolean:
"true": "sim"
"false": "não"
"": "não"
nil: "não"
"nil": "não"
But it does't work.
{:true=>"sim", :false=>"não", :""=>"não", :nil=>"não"}
If your locale file is like this:
pt-BR:
boolean:
'true': "sim"
'false': "não"
nil: "não"
then you should be able to access them with:
2.0.0-p353 :001 > I18n.locale = 'pt-BR'
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
=> "pt-BR"
2.0.0-p353 :002 > I18n.t('boolean.true')
=> "sim"
2.0.0-p353 :003 > I18n.t('boolean.nil')
=> "não"
2.0.0-p353 :004 > I18n.t('boolean.false')
=> "não"
I wanted to display datetime in words, like "1 hour ago" and i tried the following method but it is returning returning html in the string format as shown below.
method
helper.time_ago_in_words(Time.now)
result
=> "<span class=\"translation_missing\" title=\"translation missing: en.less_than_x_minutes\">Less Than X Minutes</span>"
rails console output:
>> helper.time_ago_in_words(Time.now)
=> "<span class=\"translation_missing\" title=\"translation missing: en.less_than_x_minutes\">Less Than X Minutes</span>"
>> I18n.locale = :de
=> :de
>> helper.time_ago_in_words(Time.now)
=> "<span class=\"translation_missing\" title=\"translation missing: de.less_than_x_minutes\">Less Than X Minutes</span>"
>> I18n.locale = :en
=> :en
>> helper.time_ago_in_words(Time.now)
=> "<span class=\"translation_missing\" title=\"translation missing: en.less_than_x_minutes\">Less Than X Minutes</span>"
Do you use any locales in config? English is for sure the default one and it should work correctly.
2.0.0p0 :001 > helper.time_ago_in_words(Time.now)
=> "less than a minute"
2.0.0p0 :002 > I18n.locale = :de
=> :de
2.0.0p0 :003 > helper.time_ago_in_words(Time.now)
=> "translation missing: de.datetime.distance_in_words.less_than_x_minutes"
2.0.0p0 :004 > I18n.locale = :en
=> :en
2.0.0p0 :005 > helper.time_ago_in_words(Time.now)
=> "less than a minute"
Could you try to invoke this method on helper object, like I did in console (rails c)? What is the output?
In a rails console, if I just use time_ago_in_words from ActionView::Helpers, I'll get the translation_missing error message. But if I include from ActionView::Helpers::DateHelper, it'll work as expected.
works:
[2] pry(main)> include ActionView::Helpers::DateHelper
=> Object
[3] pry(main)> time_ago_in_words(Time.now)
=> "less than a minute"
translation missing:
[1] pry(main)> include ActionView::Helpers
=> Object [2]
pry(main)> time_ago_in_words(Time.now)
=> "<span class=\"translation_missing\" title=\"translation missing: en.less_than_x_minutes\">Less Than X Minutes</span>"
Try this:
time_ago_in_words(Time.now)
So in my rails console. This is what I get if I check Time.now:
1.9.2p290 :014 > Time.now
=> 2012-02-06 01:00:43 -0500
1.9.2p290 :015 > Time.now.zone
=> "EST"
In my application.rb I have set the time zone as follows:
config.time_zone = 'Eastern Time (US & Canada)'
config.active_record.default_timezone = 'Eastern Time (US & Canada)'
However, when I store something into the database, it is still 5 hours off:
1.9.2p290 :011 > event = Event.new(:message => 'blah', :status_id => 1, :service_id => 1, :created_at => Time.now)
=> #<Event id: nil, message: "blah", status_id: 1, service_id: 1, created_at: "2012-02-06 05:55:26", updated_at: nil>
Why is it five hours off? If I compare the zones of each, this is what I get:
1.9.2p290 :016 > event.created_at.zone
=> "EST"
1.9.2p290 :017 > Time.now.zone
=> "EST"
Ok I fixed the issue. Looks like this line in application.rb was causing a problem.
config.active_record.default_timezone = 'Eastern Time (US & Canada)'
ActiveRecord will use the local time zone by default according to the ActiveRecord::Timestamp docs. http://api.rubyonrails.org/classes/ActiveRecord/Timestamp.html
in AR 3.2.1, you must either set this option to :utc or :local, or you will receive this warning:
warning: :database_timezone option must be :utc or :local - defaulting to :local