Hesham Ali Kamal
Hesham Ali Kamal

Reputation: 261

Undefined method role for Cancan in rails 3

Currently I'm implementing a simple demo for a school management system. After I login I get the following exception:

undefined method `role' for nil:NilClass
app/models/ability.rb:5:in `initialize'
app/controllers/application_controller.rb:10:in `new'
app/controllers/application_controller.rb:10:in `current_ability'

Here's ability.rb:

class Ability
  include CanCan::Ability
  def initialize(user)
    if user.role.name=='admin'
      can :manage, :all
    end

    if user.role.name=='teacher'
      can :read, Course
    end
  end
end

Here's application_controller.rb:

def set_current_user(user)
    @current_user=user
end

def current_ability
  @current_ability||= Ability.new(current_user)
end

def current_user
  @current_user
end

I authenticate the user in the users_controller.rb as:

def authenticate
  @user=User.find_by_name_and_password(params[:name],params[:password])

    if @user
      set_current_user(@user)
      respond_to do |format|
       format.html { redirect_to courses_path }
       format.json { head :no_content }
      end
    end
 end

finally here you are the method index in courses_controllers.rb, it's very simple as you can see

class CoursesController < ApplicationController
  load_and_authorize_resource
  def index
   @courses = Course.all

   respond_to do |format|
     format.html # index.html.erb
     format.json { render json: @courses }
   end
  end
 end

Any help would be greatly appreciated!

Upvotes: 2

Views: 683

Answers (1)

kubum
kubum

Reputation: 469

The error tells you that "current_user" is nil, and this is the case.

I assume that you authenticate users and then redirect them to courses_path, and it's all fine because you actually assign an instance of User to current_user. However, after the redirect it doesn't know about user and seems like session is not created.

I'd recommend you to assign session[:user_id] in authenticate, therefore you will be able to allow current_user return an instance of user during the session.

Also, you might just use Devise to handle all this logic for you.

Upvotes: 2

Related Questions