在Rails中,如何在i18n语言环境文件中指定默认的flash消息

时间:2014-03-17 23:48:55

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

我知道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时,您不必告诉它要获取哪些文本。)我一直试图通过闪存通知和警报找到解决方法。是否有类似的预设结构用于指定默认的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')都很乏味。有没有办法做到这一点,以便控制器&#34;只知道&#34;何时获取并显示区域设置文件中指定的相应Flash消息?如果是这样,这些是什么默认的YAML结构?

3 个答案:

答案 0 :(得分:28)

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

  

Rails实现了在视图

中查找区域设置的便捷方式

(强调他们,并且至少暗示我,它仅限于观点......)然而,似乎this commit to Rails带来了懒惰的&#34;也可以通过以下形式查找控制器:

"#{ 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键。

答案 1 :(得分:6)

我认为当前( 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

答案 2 :(得分:3)

@ robertwbradford关于测试的评论的后续行动,在Rails 4 / MiniTest功能(控制器)测试中,你可以在@controller实例变量上调用translate方法:

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