【问题标题】:In Rails, how to specify default flash messages in i18n locale file在 Rails 中,如何在 i18n 语言环境文件中指定默认闪存消息
【发布时间】:2014-04-23 10:44:11
【问题描述】:

我知道 i18n 语言环境文件中有一些预设结构,以便 Rails 自动提取值。例如,如果您想为新记录设置默认提交按钮文本:

# /config/locales/en.yml
en:
  helpers:
    submit:
      create: "Create %{model}"
      user:
        create: "Sign Up"

使用此集合,在视图中将产生以下结果:

# /app/views/things/new.html.erb
<%= f.submit %> #=> Renders a submit button reading "Create Thing"

# /app/views/users/new.html.erb
<%= f.submit %> #=> Renders a submit button reading "Sign Up"

所以 Rails 使用预设层次结构来获取不同模型的提交按钮文本。 (即,当使用f.submit 时,您不必告诉它要获取哪个 i18n 文本。)我一直在尝试找到一种方法来使用快速通知和警报来做到这一点。是否有类似的预设结构来指定默认的 flash 消息?

我知道您可以指定自己的任意结构,如下所示:

# /config/locales/en.yml
en:
  controllers:
    user_accounts:
      create:
        flash:
          notice: "User account was successfully created."

# /app/controllers/users_controller.rb
def create
  ...
  redirect_to root_url, notice: t('controllers.user_accounts.create.flash.notice')
  ...
end

但是每次都指定notice: t('controllers.user_accounts.create.flash.notice') 很繁琐。有没有办法做到这一点,以便控制器“只知道”何时获取和显示语言环境文件中指定的适当闪存消息?如果是这样,这些的默认 YAML 结构是什么?

【问题讨论】:

    标签: ruby-on-rails internationalization locale flash-message


    【解决方案1】:

    Rails i18n guide section 4.1.4 on "lazy" lookups 说:

    Rails 实现了一种在 views

    中查找语言环境的便捷方式

    (强调他们的,至少向我暗示,它仅限于视图......)但是,this commit to Rails 似乎也将“惰性”查找带入了控制器,关键在于形式:

    "#{ controller_path.gsub('/', '.') }.#{ action_name }#{ key }"
    

    在你的情况下应该得到你users.create.notice。

    所以,如果您对以下内容感到满意:

    # /app/controllers/users_controller.rb
    def create
      ...
      redirect_to root_url, notice: t('.notice')
      ...
    end
    

    您应该能够在以下位置声明该值:

    # /config/locales/en.yml
    en:
      users:
        create:
          notice: "User account was successfully created."
    

    我知道这并不能完全让您获得一个默认位置,Rails 会自动转到该位置并在创建用户失败时获取一个快速通知,但这比每次都输入一个完整的 i18n 密钥要好一些时间。

    【讨论】:

    • 感谢您发现这一点,@PaulFioravanti。那比较好。注意:测试时你仍然需要完整的命名空间(例如page.should have_content(t('users.create.notice')))。
    • 确实如此。 Specs 对延迟加载 i18n 值一无所知,因此在那里使用它们时总是需要完整路径。
    • 好答案。我想知道,如果像this这样的控制器键,我不需要在yams里面提到吗?
    • @ArupRakshit 如果您使用自定义键命名空间,那么我认为您将无法在控制器中使用默认的 Rails 延迟加载,而是需要完整的键路径。由于您链接的答案中提到的 I18nLazyLookup gem 似乎支持控制器,我想说试一试,看看它是否符合您的要求。
    【解决方案2】:

    我认为目前(2015 年秋季)为控制器实现惰性闪存消息的最优雅且有些传统的方法是使用responders gem:

    gem 'responders', '~> 2.1'
    

    FlashResponder 根据控制器动作设置闪光灯 资源状况。例如,如果您这样做:respond_with(@post) 在 POST 请求和资源@post 不包含错误,它将 只要你配置好你的 I18n 文件,就会自动将 flash 消息设置为"Post was successfully created":

    flash:
      actions:
        create:
          notice: "%{resource_name} was successfully created."
        update:
          notice: "%{resource_name} was successfully updated."
        destroy:
          notice: "%{resource_name} was successfully destroyed."
          alert: "%{resource_name} could not be destroyed."
    

    这允许从控制器中完全删除与flash 相关的代码。

    但是,正如您已经了解的那样,您需要使用他们的 respond_with 方法重写您的控制器:

    # app/controllers/users_controller.rb
    
    class UsersController < ApplicationController
      respond_to :html, :json
    
      def show
        @user = User.find params[:id]
        respond_with @user
      end
    end
    

    【讨论】:

      【解决方案3】:

      跟进@robertwbradford 对测试的评论,在Rails 4 / MiniTest 功能(控制器)测试中,您可以在@controller 实例变量上调用translate 方法:

      assert_equal @controller.t('.notice'), flash[:notice]
      

      【讨论】:

        猜你喜欢
        • 2020-07-07
        • 1970-01-01
        • 1970-01-01
        • 2014-09-14
        • 1970-01-01
        • 1970-01-01
        • 2011-04-15
        • 1970-01-01
        • 2017-06-02
        相关资源
        最近更新 更多