简体   繁体   English

Rails的nil:NilClass未定义方法错误

[英]Rails Undefined Method Error for nil:NilClass

So in my rails app, I have users with different permissions. 因此,在我的Rails应用程序中,我的用户具有不同的权限。 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. 我想我完全理解发生这种情况的原因:因为没有人登录,Rails试图弄清楚他们扮演的角色,并且因为没有人登录而没有角色,所以Rails不知道它是否应该显示页面与否。

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. 这可以通过使用CanCanCan并从控制器提取授权逻辑来简化。 With cancan abilities set up, controller code usually looks like this: 设置cancan功能后,控制器代码通常如下所示:

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? 您当前正在呼叫editor? on a nil object, which is throwing an error. nil对象上,这将引发错误。 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. 通过使用上述技术,您首先要检查以确保current_user不为nil ,然后对current_user是否存在进行检查,如果不存在,则仅返回false并重定向到/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创建一个重定向到错误页面的方法,然后仅在您要确保用户已登录的操作上添加一个before_action

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 如果您使用的是devise gem,则有一个用于要求身份验证的回调/过滤器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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