在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]