Pundit Decorator
Public
15 Oct 08:30

Organize Pundit error messages and redirects in a decorator. Simplify reuse and maintenance

Create a decorator for the pundit error

class PunditErrorDecorator
  def initialize(error)
    @query = error.query
    @record = error.record
    @policy = error.policy
  end

  def message
    return policy_message(:cannot_see_draft) if custom_condition
    default_message
  end

  def redirect_path
    return error.record if custom_condition
    [:root]
  end

  private

  def policy_message(key)
    I18n.t(key, scope: [:pundit, @policy.class.name.underscore])
  end

  def default_message
    I18n.t('pundit.default')
  end

  # ...
end

And translations for error messages

en:
  pundit:
    default: You do not have permission to perform this action
    some_model:
      cannot_see_draft: You cannot read this post before publication

Display the message as flash to end users and redirect them

rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

private

def user_not_authorized(error)
  error = PunditErrorDecorator.new(error)
  redirect_to error.redirect_path, alert: error.message
end

Or as json error message in API

rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

private

def user_not_authorized(error)
  error = PunditErrorDecorator.new(error)
  render status: :forbidden, json: { error: error.message }
end

Comments

Empty! You must sign in to add comments.