В Rails, как указать флэш-сообщения по умолчанию в локальном файле i18n
Я знаю, что в локальном файле 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"
So Rails использует предустановленную иерархию для получения текста кнопки отправки для разных моделей. (т.е. вам не нужно указывать, какой текст i18n получить при использовании f.submit
.) Я пытался найти способ сделать это со вспышками уведомлений и предупреждений. Есть ли аналогичная предустановленная структура для указания флэш-сообщений по умолчанию?
Я знаю, что вы можете указать свои собственные произвольные структуры, такие как:
# /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 по умолчанию для них?
Ответы
Ответ 1
Раздел Rails i18n Guide 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 каждый время.
Ответ 2
Я думаю, что в текущее время (осень 2015) самый изящный и несколько условный способ реализации ленивых флеш-сообщений для вас - использовать responders
gem:
gem 'responders', '~> 2.1'
FlashResponder
устанавливает вспышку на основе действия контроллера и статус ресурса. Например, если вы выполните: respond_with(@post)
на POST-запрос, а ресурс @post
не содержит ошибок, он будет автоматически установите флэш-сообщение на "Post was successfully
created"
, пока вы настраиваете свой файл I18n:
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
Ответ 3
Последующее наблюдение за комментарием @robertwbradford при тестировании в тестовом режиме Rails 4/MiniTest (контроллер) вы можете вызвать метод перевода в переменной экземпляра @controller:
assert_equal @controller.t('.notice'), flash[:notice]