23

我知道 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 使用预设的层次结构来获取不同模型的提交按钮文本。(即,您不必告诉它在使用 . 时要获取哪个 i18n 文本f.submit。)我一直在尝试找到一种方法来使用 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 结构是什么?

4

3 回答 3

31

Rails i18n 指南第4.1.4 节关于“惰性”查找说:

Rails 实现了一种在视图中查找语言环境的便捷方法

(强调他们的,至少向我暗示,它仅限于视图......)然而,似乎这个对 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 密钥要好一点。

于 2014-03-18T14:13:58.163 回答
8

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

gem 'responders', '~> 2.1'

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

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从控制器中完全删除 -related 代码。

但是,正如您已经了解的那样,您需要使用他们的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
于 2015-10-27T00:51:10.003 回答
4

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

assert_equal @controller.t('.notice'), flash[:notice]
于 2015-03-02T20:50:02.927 回答