I am using I18n internationnalization plugin, but it's not translating 1 piece of information :
In one of my controller, I have a verify method like this :
# Verify user is authenticated
verify :only => [ :destroy, :create, :update, :new, :comment ],
:session => :user_id,
:add_flash => { :error => I18n.t(:'Exceptions.not_logged_in') },
:redirect_to => { :controller => 'main' , :action => 'index' }
However, using I18n.t(:'Exceptions.not_logged_in') always display the default_locale, in this case, english.
I have in my Application_Controller a before_filter that sets the locale.
Can anybody help me understand, and help me find a workaround?
Thanks!
P.S.: I tried adding a call to set_locale before this verification method without success (in my controller)
Since verify
is a class method called at the class definition level, its arguments, including the I18n.t
call, are evaluated as the controller is loaded. In order for I18n.t
to work properly, it needs to be evaluated each time the relevant controller actions are executed. verify
does not have the ability to do this.
Instead, I suggest you use a before filter:
before_filter :verify_session, :only => [:destroy, :create, :update, :new, :comment]
def verify_session
unless session[:user_id]
flash[:error] = I18n.t('Exceptions.not_logged_in')
redirect_to :controller => 'main', :action => 'index'
end
end
Also, note that verify
has been deprecated and moved to a plugin in Rails 3, while before filters continue to work.
The translation is in the wrong place; the translated version of the message is strictly a user interface issue so the translation should occur at the user interface level. The FlashHash should only contain error condition identifiers of some sort, the user interface code should deal with converting that to something a human can understand:
verify :only => [ :destroy, :create, :update, :new, :comment ],
:session => :user_id,
:add_flash => { :error => 'Exceptions.not_logged_in' },
:redirect_to => { :controller => 'main' , :action => 'index' }
And then, later in some ERB or whatever:
<% if flash[:error] %>
<p class="error"><%= I18n.t(flash[:error]) %></p>
<% end %>
This approach also makes it easy to push error IDs all the way to a REST client or JavaScript front end without forcing them to deal with parsing ever-changing error messages:
if((flash.error || '') == 'Exceptions.not_logged_in')
sammy.setLocation('#/sign_in');
I can't be the only person whose error handling code broke after an upgrade because someone changed an error message and didn't offer any error mechanism that was meant to be consumed by software rather than humans.
Put the call to I18n.t in parens
add_flash => { :error => (I18n.t(:'Exceptions.not_logged_in')) },
I think it might have something to do with that I18n.t call being run only once when the file is initially loaded on app startup. You could try wrapping it in a Proc or lambda or maybe in a separate method. e.g. something like:
:add_flash => lambda { { :error => I18n.t(:'Exceptions.not_logged_in') } }
No idea if that'll work, but it might get you closer.
来源:https://stackoverflow.com/questions/1402345/rails-i18n-in-verification-rb-verify-method-does-not-work