简体   繁体   中英

How do I specify a custom exception message from my ability.rb?

In my ability.rb , I have the following rule:

elsif user.has_role? :demo
  can :read, Profile, demo_featured: true, demo_linked: true, message: "To access this profile, please subscribe here."

But that doesn't produce the message I want.

How do I get this specific rule to produce the message I want?

Edit 1

Here is the full ability.rb if condition:

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    alias_action :create, :show, :new, :destroy, to: :csnd

    if user.has_role? :admin
      can :manage, :all
    elsif user.has_role? :coach
      # do some stuff
    elsif user.has_role? :demo
      can :read, Profile, demo_featured: true, demo_linked: true
    elsif user.has_role? :player
      # can do some stuff
    else
      can :read, Profile
    end    
  end

These are some bits from my ProfilesController :

  before_action :set_profile, only: [:show, :edit, :update, :destroy, :invite_user, :profiles]

    def set_profile
      @profile = Profile.published.includes(:grades, :positions, :achievements, :videos, :transcripts).friendly.find(params[:id])
    end

The cancan docs give examples of customizing the message when you authorize! in the controller, and when you manually raise an error, but there doesn't seem to be any mechanism for specifying messages in ability.rb .

Instead, you could catch and modify it in your ApplicationController :

class ApplicationController < ActionController::Base
  rescue_from CanCan::AccessDenied do |exception|
    if current_user.has_role? :demo
      redirect_to :back, :alert => "To access this profile, please subscribe here."
    end
    # render 403, etc.
  end
end

Look for rescue_from CanCan::AccessDenied in your main application controller or in your specific controller. It should do something like redirecting to a login page. In my case it's something like this:

rescue_from CanCan::AccessDenied do ||
  redirect_to new_user_session_path
end

Since you're producing a different exception message and then displaying it it'd probably be like this, using the flash:

rescue_from CanCan::AccessDenied do |exception|
  flash[:notice] = exception.message
  redirect_to new_user_session_path
end

Your own logic may vary depending on how you want to handle when the user doesn't have access. It's possible you may even have it setup in a per-controller basis, but this should be the gist of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM