【问题标题】:Rails I18n in verification.rb verify method does not work?在verify.rb中的Rails I18n验证方法不起作用?
【发布时间】:2009-09-09 21:53:51
【问题描述】:

我正在使用 I18n 国际化插件,但它没有翻译一条信息:

在我的一个控制器中,我有一个这样的验证方法:

  # 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' }

但是,使用 I18n.t(:'Exceptions.not_logged_in') 始终显示 default_locale,在本例中为英语。

我的 Application_Controller 中有一个用于设置语言环境的 before_filter。

谁能帮助我理解并帮助我找到解决方法?

谢谢!

P.S.:我尝试在此验证方法之前添加对 set_locale 的调用但没有成功(在我的控制器中)

【问题讨论】:

    标签: ruby-on-rails ruby internationalization


    【解决方案1】:

    由于verify 是在类定义级别调用的类方法,其参数(包括I18n.t 调用)在加载控制器时进行评估。为了使I18n.t 正常工作,每次执行相关控制器操作时都需要对其进行评估。 verify 没有这个能力。

    相反,我建议您使用前置过滤器:

    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
    

    另外,请注意 verify 已被弃用并移至 Rails 3 中的插件,而在过滤器继续工作之前。

    【讨论】:

      【解决方案2】:

      翻译放错地方了;消息的翻译版本严格来说是用户界面问题,因此翻译应该在用户界面级别进行。 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 %>
      

      这种方法还可以轻松地将错误 ID 一直推送到 REST 客户端或 JavaScript 前端,而无需强制它们处理不断变化的错误消息的解析:

      if((flash.error || '') == 'Exceptions.not_logged_in')
          sammy.setLocation('#/sign_in');
      

      我不可能是唯一一个在升级后错误处理代码中断的人,因为有人更改了错误消息并且没有提供任何旨在由软件而非人类使用的错误机制。

      【讨论】:

      • 我想对此投赞成票,但显然 SO 认为我之前曾对此投过票,除非您先编辑一下,否则我不会这样做。
      • 好的,现在我可以投票给你了。但我记得几天前我想给你投赞成票,但我错误地按下了反对票,然后很快按下了赞成票,它起作用了,取消了我的反对票。但是,当我实际上试图对你投赞成票时,它并没有让我这样做。等了几天,没有任何变化。所以可能是一个错误。
      • @Behrang:是的,听起来好像有什么东西在 SO 的内部某处卡住了。我现在将退出我的“使其可投票”编辑。
      【解决方案3】:

      在括号中调用 I18n.t

      add_flash => { :error => (I18n.t(:'Exceptions.not_logged_in')) },
      

      【讨论】:

        【解决方案4】:

        我认为这可能与 I18n.t 调用在应用程序启动时最初加载文件时仅运行一次有关。您可以尝试将其包装在 Proc 或 lambda 或单独的方法中。例如类似:

        :add_flash => lambda { { :error => I18n.t(:'Exceptions.not_logged_in') } }
        

        不知道这是否可行,但它可能会让你更接近。

        【讨论】:

        • 好主意,但它似乎拒绝在那里有一个 Proc。错误消息是“没有为类 Proc 定义 marshal_dump”
        猜你喜欢
        • 1970-01-01
        • 2012-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-20
        相关资源
        最近更新 更多