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

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

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

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

 # /app/views/things/new.html.erb  #=> Renders a submit button reading "Create Thing" # /app/views/users/new.html.erb  #=> Renders a submit button reading "Sign Up" 

因此,Rails使用预设层次结构来获取不同模型的提交按钮文本。 (也就是说,你不必告诉它在使用f.submit时要获得哪些i18n文本。)我一直试图找到一种方法来使用flash通知和警报。 是否有类似的预设结构来指定默认的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')是很繁琐的。 有没有办法做到这一点,以便控制器“只知道”何时抓取并显示在语言环境文件中指定的相应Flash消息? 如果是这样,这些的默认YAML结构是什么?

关于“懒惰”查找的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键要好一些。

我认为当前( 2015年秋季 )为您的控制器实现延迟闪存消息的最优雅和有点传统的方法是使用responders gem:

 gem 'responders', '~> 2.1' 

FlashResponder根据控制器操作和资源状态设置闪存。 例如,如果您对POST请求执行: respond_with(@post)并且资源@post不包含错误,则只要您配置I18n文件,它就会自动将Flash消息设置为"Post was successfully created" @post "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 

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

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