Pundit gem. Is there way to show record's specific attribute values over yml file?
i'am playing with pundit gem. i need to show post's title
in a flash message
#config/locales/pundit.en.yml
en:
pundit:
default: 'You cannot perform this action.'
post_policy:
share?: 'You cannot share post %{post.title}!'
контроллер:
#posts_controller.rb
def share
@post = Post.find(params[:id])
authorize @post
@post.share
redirect_to @post
end
all i receive is the exact the same string without any errors and substitutions
You cannot share post %{post.title}!
какие-либо предложения? Спасибо
2 ответа
Модуль I18n не может знать, что post.title
относится к @post.title
, Rails делает некоторую магию с помощниками, но эта магия не распространяется на Pundit.
Вот как документы Pundit предлагают настроить ваши сообщения об ошибках:
Создание пользовательских сообщений об ошибках
NotAuthorizedError
предоставить информацию о том, что запрос (например,:create?
) какая запись (например, экземплярPost
) и какую политику (например, экземплярPostPolicy
) вызвало ошибку.Один из способов использовать эти
query
,record
, а такжеpolicy
свойства, чтобы связать их сI18n
генерировать сообщения об ошибках. Вот как вы можете сделать это.class ApplicationController < ActionController::Base rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized private def user_not_authorized(exception) policy_name = exception.policy.class.to_s.underscore flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default redirect_to(request.referrer || root_path) end end
en: pundit: default: 'You cannot perform this action.' post_policy: update?: 'You cannot edit this post!' create?: 'You cannot create posts!'
Конечно, это всего лишь пример. Pundit не зависит от того, как вы реализуете свои сообщения об ошибках.
Из этой информации мы можем экстраполировать что-то вроде следующего:
private
def user_not_authorized(exception)
policy_name = exception.policy.class.to_s.underscore
interpolations = exception.query == 'share?' ? { title: @post.title } : {}
flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default, **interpolations
redirect_to(request.referrer || root_path)
end
А потом, в ваших местах:
en:
pundit:
default: You cannot perform this action.
post_policy:
share?: You cannot share post %{title}!
У меня нет приложения с Pundit передо мной, поэтому я не могу проверить это; скорее всего, вам нужно будет немного уловить это.
Проблема в том, что одинарные (') кавычки не допускают интерполяции строк только двойные (") кавычки
Взято из программирования Ruby
Строки в двойных кавычках (...) могут подставлять значение любого выражения Ruby в строку, используя последовательность #{ expr }. Если выражение является просто глобальной переменной, переменной класса или переменной экземпляра, вы можете опустить фигурные скобки.