2

I am using gem 'devise' and 'cancancan' for defining roles for user. problem is when I run rails server its says: undefined method 'admin?' for nil:NilClass

ability.rb:

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.admin?
      can :manage, :all
    else
      can :read, :all
    end
  end
end

User model:

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :projects

  def admin?
    self.admin
  end
end

What could be the problem?

Vinz_B
  • 57
  • 1
  • 10
  • you don't have a current user so this fails you could add a guard clause or implement in the same fashion as the [Abilities Docs](https://github.com/CanCanCommunity/cancancan/wiki/defining-abilities) – engineersmnky May 17 '17 at 14:42

2 Answers2

2

I'm guessing the line from where the error is originating is something like:

if can? :manage, @object
  # ...

This is likely causing an error because your user is not logged in.

The method defining the abilities looks like this:

def initialize(user)
  if user.admin?
    can :manage, :all
  else
    can :read, :all
  end
end

So, if you have no user, the line user.admin? will cause an error because user is nil and nil has no admin? method.

I would do something like this:

def initialize(user)
  if user.try(:admin?)
    can :manage, :all
  else
    can :read, :all
  end
end

try in Ruby won't throw an error but will return nil if the method doesn't exist.

(I have not tested this and since you're not sharing the error, I'm taking some liberties in the response.)


I'd also like to point out that if the admin attribute on your User model is a boolean, you don't need to define this method—Rails does that automatically for you.

def admin?
  self.admin
end
seancdavis
  • 2,739
  • 2
  • 26
  • 36
0

ability

class Ability
 include CanCan::Ability

  def initialize(user)
    if user.has_role? :admin
     can :manage, :all
    else
     can :read, :all
    end
  end
end
Pedro Holguin
  • 66
  • 1
  • 4
  • This method is used with rolify [link](https://github.com/RolifyCommunity/rolify/wiki/Devise---CanCanCan---rolify-Tutorial) – Pedro Holguin May 17 '17 at 15:16
  • The OP mentioned nothing about rolify, and the user model he's showing does not have a `has_role?` method. – seancdavis May 17 '17 at 15:51