Подтвердить что ты не робот

В 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 по умолчанию для них?

4b9b3361

Ответ 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]