title: Pundit policy_scope error: undefined method `admin?' for nil:NilClass
body: <p>Running into something I don't understand with Pundit,</p>
  
  <p>Using Rails 4.2.5.1, Pundit 1.1.0 with Devise for authentication.</p>
  
  <p>I'm trying to use a policy scope for the BlogController#Index action.</p>
  
  <ul>
  <li>If user is admin, display all posts (drafts, published)</li>
  <li>If user is standard, display posts marked published only</li>
  <li>If no user / user not logged in, display posts marked published only</li>
  </ul>
  
  <p>Getting an error:</p>
  
  <blockquote>
    <p>undefined method `admin?' for nil:NilClass</p>
  </blockquote>
  
  <p>Live shell reveals:</p>
  
  <pre><code>&gt;&gt; user
  =&gt; nil
  </code></pre>
  
  <hr>
  
  <pre><code># ApplicationController
  class ApplicationController &lt; ActionController::Base
    include Pundit
    rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
  
    # Prevent CSRF attacks by raising an exception.
    # For APIs, you may want to use :null_session instead.
    protect_from_forgery with: :exception
  
    private
  
      def user_not_authorized
        flash[:error] = "You are not authorized to perform this action."
        redirect_to(request.referrer || root_path)
      end
  end
  </code></pre>
  
  <hr>
  
  <pre><code># BlogController
  
  # == Schema Information
  #
  # Table name: blogs
  #
  #  id         :integer          not null, primary key
  #  title      :string           default(""), not null
  #  body       :text             default(""), not null
  #  published  :boolean          default("false"), not null
  #  created_at :datetime         not null
  #  updated_at :datetime         not null
  #
  
  class BlogsController &lt; ApplicationController
    before_action :set_blog, only: [:show, :edit, :update, :destroy]
    before_action :authenticate_user!, except: [:index, :show]
  
    after_action :verify_authorized, except: [:index, :show]
    after_action :verify_policy_scoped, only: [:index]
  
    def index
      @blogs = policy_scope(Blog)
      authorize @blog
    end
  
    def show
    end
  
    def new
      @blog = Blog.new
      authorize @blog
    end
  
    def edit
      authorize @blog
    end
  
    def create
      @blog = Blog.new(blog_params)
      @blog.user = current_user if user_signed_in?
  
      authorize @blog
  
      if @blog.save
        redirect_to @blog, notice: "Blog post created."
      else
        render :new
      end
    end
  
    def update
      authorize @blog
  
      if @blog.update(blog_params)
        redirect_to @blog, notice: "Blog updated."
      else
        render :edit
      end
    end
  
    def destroy
      authorize @blog
      @blog.destroy
      redirect_to blogs_url, notice: "Blog post deleted."
    end
  
    private
  
      def set_blog
        @blog = Blog.friendly.find(params[:id])
      end
  
      def blog_params
        params.require(:blog).permit(*policy(@blog|| Blog).permitted_attributes)
      end
  end
  </code></pre>
  
  <hr>
  
  <pre><code># Application Policy
  
  class ApplicationPolicy
    attr_reader :user, :record
  
    def initialize(user, record)
      @user = user
      @record = record
    end
  
    def index?
      false
    end
  
    def show?
      scope.where(:id =&gt; record.id).exists?
    end
  
    def create?
      false
    end
  
    def new?
      create?
    end
  
    def update?
      false
    end
  
    def edit?
      update?
    end
  
    def destroy?
      false
    end
  
    def scope
      Pundit.policy_scope!(user, record.class)
    end
  
    class Scope
      attr_reader :user, :scope
  
      def initialize(user, scope)
        @user = user
        @scope = scope
      end
  
      def resolve
        scope
      end
    end
  end
  </code></pre>
  
  <hr>
  
  <pre><code># Blog Policy
  
  class BlogPolicy &lt; ApplicationPolicy
    class  Scope &lt; Scope
      def resolve
        if user.admin?
          scope.all
        else
          scope.where(published: true)
        end
      end
    end
  
    def new?
      user.admin?
    end
  
    def index?
      true
    end
  
    def update?
      user.admin?
    end
  
    def create?
      user.admin?
    end
  
    def destroy?
      user.admin?
    end
  
    def permitted_attributes
      if user.admin?
          [:title, :body]
      end
    end
  end
  </code></pre>
  
  <hr>
  
  <p>In the Pundit BlogPolicy scope I've created:</p>
  
  <pre><code>  class  Scope &lt; Scope
      def resolve
        if user.admin?
          scope.order('id DESC')
        else
          scope.where('published: true')
        end
      end
    end
  </code></pre>
  
  <blockquote>
    <p>If I log in as an <code>admin user</code> it works fine.</p>
  </blockquote>
  
  <p>I'm able to view all blog posts.</p>
  
  <blockquote>
    <p>If I log in as a standard <code>user</code> it works.</p>
  </blockquote>
  
  <p>Standard user sees blog posts that are marked published.</p>
  
  <blockquote>
    <p>If I'm not logged in where <code>user is nil</code> I get an error:</p>
  </blockquote>
  
  <pre><code>NoMethodError at /blog
  undefined method `admin?' for nil:NilClass
  </code></pre>
  
  <p>I can add another clause <code>elsif user.nil?</code> before <code>user.admin?</code> or a <code>case when</code> statement but I thought if the user is not an admin it should just display what is in the else block?</p>
  
  <pre><code> # This seems wrong?
  
    class  Scope &lt; Scope
      def resolve
        if user.nil?
          scope.where('published: true')
        elsif user.admin?
          scope.all
        else
          scope.where('published: true')
        end
      end
    end
  </code></pre>
  
  <p>Any pointers much appreciated   </p>