I'm having some problems with Rails I18n, more specifically with the keys in errors.messages.
The issue is that Rails itself define some translations (
https://github.com/svenfuchs/rails-i18n/blob/a7d33d1b319bdbaa1da64ced0aa0d280891a3a09/rails/locale/en.yml#L101 ). Example:
errors:
messages:
accepted: must be accepted
blank: can't be blank
present: must be blank
confirmation: doesn't match %{attribute}
empty: can't be empty
...
But Devise also defines some translations in errors.messages ( https://github.com/tigrish/devise-i18n/blob/ab598c6fdd8a029c9853fcf22788c27b828fae31/rails/locales/en.yml#L50 ). Example:
errors:
messages:
already_confirmed: was already confirmed, please try signing in
confirmation_period_expired: needs to be confirmed within %{period}, please request a new one
expired: has expired, please request a new one
not_found: not found
not_locked: was not locked
If Devise translation file is loaded before Rails translation file, it will be overwritten and vice-versa.
Is there a solution for this besides merging these keys manually in the same file?
You need not curb both the files together,
You can do the devise specific translations using the devise.es.yml in your config/locales folder. See here:
https://github.com/plataformatec/devise/wiki/I18n
while having your other messages in en.yml
Hope it helps!
Related
I have ru.yml and en.yml files, the section I need looks like this:
en:
devise:
failure:
already_authenticated: You are already signed in.
ru:
devise:
failure:
already_authenticated: Вы уже вошли в систему.
The thing is, that no matter what language the user chooses, this (and several others) alert messages will be in russian.
My controllers have around_action :localize_request, which should determine the locale. And it works just fine for any other funcionality on the site, except for this particular case.
I think it could be a possible bug from devise. Take a look at this issue they discussed something similar and created a PR to fix it that I think is the reason why you can't translate your message.
As a workaround, maybe you can try to make this change to test if it works:
ru:
devise:
failure:
user: # <<<
already_authenticated: Вы уже вошли в систему.
Looks like it's a bug in the Devise gem -- https://github.com/heartcombo/devise/issues/5247
I know you can change ActiveRecord error messages in the locales like this:
en:
activerecord:
errors:
models:
user:
attributes:
email:
blank: "is required"
But that is an incredibly specific tree—how do I know what ActiveRecord is looking for? Is there a way to inspect an error to see what path ActiveRecord is searching? Or is there a way to generate a complete en.yml with all messages in there?
The ActiveModel::Error class (what you get if you call record.errors) has a details attribute, which is a hash of the attributes and their errors, including the error key.
foo.valid?
=> false
foo.errors.details
=> {:user=>[{:error=>:blank}]}
The ActiveModel source has an en.yml, which will give you the canonical set of keys. The rails-i18n gem includes translations for many of the standard keys, but there are definite gaps (that is, some locales are complete, some are not).
As #Mirror318 says, you can see the set of error message translations for the current locale by running I18n.t 'errors'. If your current locale is en.yml that will be the same as the canonical list; otherwise it is the available set of translated messages.
In a Rails console, you can enter:
I18n.t 'errors'
And that will return a hash of all current error messages. You can adjust that hash via the locale .yml file
I've a project that implements devise and I'm having trouble overriding the Passwords controller's messages.
When a wrong email address is entered by the user, Devise by default gives
Unable to find user with email {email}
I cant find the key to override this message in the devise.en.yml and can't find anything with the similar message on the devise repo as well.
Do I have an option other than to override the controller? Any help is appreciated.
Thanks
Add a new locale having the following structure:
en:
devise_token_auth:
passwords:
user_not_found: "Your custom message"
This message will be displayed when an invalid email is passed in the forgot password form.
Originally this message comes from the devise_token_auth gem. But if you have the same locale in your locale files, it will override the gem's locale.
It doesn't matter which *.en.yml file you will put this locale into. It can be devise.en.yml, or you can add a new file called devise_token_auth.en.yml. Only the structure matters.
as described in the following link you can generate the devise controller with
rails generate devise:controllers user
then you can over-ride the create or update action. If you include super in the new action, it will call the parent controller action and then execute the code.
You can also over-ride the devise messages as explained in this post, you just need to create that locale in your settings
en:
devise_token_auth:
sessions:
not_confirmed: "your message overwritten"
I am building a car rental app with Ruby on Rails and currently I have been coding with English. Basically I have an user and car model, where user can login, sign in, log out and list their car.
I would like to implement another language allowing the user to select English or Spanish from a dropdown. I have default error messages returns from the controller actions such as "can't be blank, already used" etc. And I also have custom JS messages, such as if user successfully adds a car, jQuery returns "your car has been published". Lastly, I also have Flash messages. But I do not know how should I handle errors, custom JS and Flash messages in the YML file according to user's language selection.
It actually really depends on the structure of your YAML file, for example, for ActiveRecord error messages:
it:
errors:
format: "%{attribute} %{message}"
messages: &errors_messages
empty: "non può essere vuoto"
blank: "non può essere lasciato in bianco"
If you want to access I18n (a.k.a Internationalization) outside of views, you can use I18n.t(your_key), which is in fact the helper you have access to in your views. So for example, if you wish to translate a notice in a controller you could be doing something like:
def your_action
redirect_to other_path, notice: I18n.t("notices.successful_action")
end
And then having in your YAML the correspondent structure:
en:
notices:
successful_action: "You did it!"
Hope this helps!
I do not know how should I handle error, custom js and flash messages in yml file according to user's language selection
For Rails app-related translations in general, including error messages, the Rails i18n gem has you covered. You can see what languages have been translated in the gem's locale file.
For specifically overriding error messages or creating new ones, see The Rails Guide sections on looking up translations and translations for ActiveRecord models to see what keys in your YAML files you should be putting your translations under.
For flash messages, have a look at this StackOverflow question to see how you can use lazy lookups (eg t('.notice')) in your controllers.
For the ability to use translations in Javascript files in the same way you do in Ruby (eg I18n.t("my_translation"), and be able to manage those translations in your YAML files with the rest of your Rails translations, have a look at the i18n-js gem. Setup instructions are in the README file.
I'm using the standard Rails I18n API to localise some of our views. This is working really well, but we now have a few use cases for regional changes to the en locale.
The API guide mentions that this isn't supported directly, and other plugins should be used. However, I'm wondering whether there's a simpler way to do this.
I already have en.yml, so in theory I could just create en-AU.yml and en-US.yml which are effectively clones of en.yml but with a few regional changes applied. I could then add additional English - American and English - Australian options to our configuration which would map to the new region-specific locales and allow users to use a region-specific locale.
The only problem I can think of with this is that it isn't DRY -- I would have duplicate translations for all common English words. I can't see a way around this.
Are there any other disadvantages to this approach, or should I just bite the bullet and dive into one of the plug-ins such as Globalize2 instead?
The rails-i18n-translation-inheritance-helper is getting a bit old now, so here's my approach for a Rails 3.2 project.
If you keep both en-US and en-AU in the same en.yml file you can use the yml repeated node to have a super en section:
For example:
en: &en
errors:
messages:
expired: "has expired, please request a new one"
not_found: "not found"
en-US:
<<: *en
en-AU:
<<: *en
errors:
messages:
not_found: "tis not found"
I'm using translation inheritance helper plugin for this.
In newer versions of Rails/i18n, they've added a fallback feature. Works similar to the outdated translation inheritance helper gem
see this answer for more info: Fall back to default language if translation missing