В 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"

Поэтому 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 по умолчанию?


person robertwbradford    schedule 17.03.2014    source источник


Ответы (3)


В разделе 4.1.4 руководства Rails i18n по "ленивому" поиску говорится:

В 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.

person Paul Fioravanti    schedule 18.03.2014
comment
Спасибо, что нашли это, @PaulFioravanti. Так лучше. Примечание. При тестировании вам все равно потребуется полное пространство имен (например, page.should have_content(t('users.create.notice'))). - person robertwbradford; 18.03.2014
comment
Это правда. Спецификации ничего не знают о ленивой загрузке значений i18n, поэтому вам всегда понадобится полный путь при их использовании там. - person Paul Fioravanti; 19.03.2014
comment
Хороший ответ. Я хотел бы знать, не нужно ли мне упоминать внутри ямса ключ контроллера, например this? - person Arup Rakshit; 17.01.2016
comment
@ArupRakshit, если вы используете настраиваемые пространства имен ключей, то я думаю, что вы не сможете использовать отложенную загрузку Rails по умолчанию в контроллерах, и вместо этого вам потребуется полный путь к ключу. Поскольку гем I18nLazyLookup, упомянутый в ответе, на который вы ссылаетесь, похоже, поддерживает контроллеры, я бы посоветовал попробовать и посмотреть, делает ли он то, что вы хотите. - person Paul Fioravanti; 18.01.2016

Я думаю, что в настоящее время (осень 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
person jibiel    schedule 27.10.2015

В дополнение к комментарию @robertwbradford о тестировании, в функциональном (контроллерном) тесте Rails 4 / MiniTest вы можете вызвать метод перевода для переменной экземпляра @controller:

assert_equal @controller.t('.notice'), flash[:notice]
person Lucas Nelson    schedule 02.03.2015