简体   繁体   中英

Rails Undefined Method Error for nil:NilClass

So in my rails app, I have users with different permissions. When someone is logged in, everything works perfectly. However, when no one is logged in, I get the following error:

Undefined method 'editor?' for nil:NilClass

def require_editor
    redirect_to '/error' unless current_user.editor? || current_user.admin?
end

I think I understand exactly why this is happening: because no one is logged in, Rails is trying to figure out what role they have, and because there is no role for someone not logged it, Rails doesn't know if it should show the page or not.

My question is: How can I make a default role for someone who is not logged in, and send them to the error page that says they don't have permission?

I usually do something like this:

class ApplicationController

  def current_user_or_guest
    current_user || Guest.new
  end

  class Guest
    def editor?
      false
    end

    def admin?
      false
    end
  end
end

Then simply

def require_editor
  redirect_to '/error' unless current_user_or_guest.editor? || current_user_or_guest.admin?
end

This could be simplified by using CanCanCan and extracting authorization logic from the controller. With cancan abilities set up, controller code usually looks like this:

def require_editor
  redirect_to '/error' unless can?(:edit, MyThing)
end
def require_editor
    redirect_to '/error' unless current_user && (current_user.editor? || current_user.admin?)
end

You're currently calling editor? on a nil object, which is throwing an error. By using the technique above, you're first checking to ensure current_user is not nil , and then perform the checks on current_user if it exists, if not it simply returns false and redirects to the /error URL.

Inside your ApplicationController create a method that redirects to the error page then add a before_action only on the actions that you wanna make sure the user is signed in

ApplicationController

def require_editor
  unless current_user && (current_user.editor? || current_user.admin?)
    redirect_to '/error' 
  end
end

Controller you wanna raise this error

class Controller < ApplicationController
  before_action :require_editor
  def new

  end
end 

If you are using devise gem there is a callback/filter for requiring authentications

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-2025 STACKOOM.COM