我知道 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 文本。我一直在尝试找到一种方法来通过闪电通知和警报来做到这一点。是否有类似的预设结构来指定默认闪存消息?
我知道您可以指定自己的任意结构,如下所示:
# /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 结构是什么?
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
根据控制器操作设置闪光灯,并且 资源状态。例如,如果您这样做: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
跟进@robertwbradford对测试的评论,在 Rails 4/MiniTest 功能(控制器(测试中,您可以在 @controller 实例变量上调用 translate 方法:
assert_equal @controller.t('.notice'), flash[:notice]