Перевод находится не в том месте; переведенная версия сообщения является строго проблемой пользовательского интерфейса, поэтому перевод должен происходить на уровне пользовательского интерфейса. FlashHash должен содержать только идентификаторы условий ошибки некоторого вида, код пользовательского интерфейса должен иметь дело с преобразованием этого в нечто, понятное человеку:
verify :only => [ :destroy, :create, :update, :new, :comment ],
:session => :user_id,
:add_flash => { :error => 'Exceptions.not_logged_in' },
:redirect_to => { :controller => 'main' , :action => 'index' }
А потом, позже, в каком-нибудь ERB или где-то еще:
<% if flash[:error] %>
<p class="error"><%= I18n.t(flash[:error]) %></p>
<% end %>
Этот подход также позволяет легко отправлять идентификаторы ошибок на REST-клиент или клиентский интерфейс JavaScript, не вынуждая их разбирать постоянно меняющиеся сообщения об ошибках:
if((flash.error || '') == 'Exceptions.not_logged_in')
sammy.setLocation('#/sign_in');
Я не могу быть единственным человеком, чей код обработки ошибок сломался после обновления, потому что кто-то изменил сообщение об ошибке и не предложил никакого механизма ошибок, который должен был использоваться программным обеспечением, а не людьми.