Search code examples
ruby-on-railscancanuser-rolescancancan

Rails, Devise, Role Model and CanCanCan - defining abilities


I am using Rails 4 to make a web app.

I am trying to use CanCanCan to define abilities for the various roles.

I have a User model and a Profile model. Each user can have many profiles. Each profile can have a different role.

In my Profile.rb, I have defined my roles (using Role Model gem) as:

  include RoleModel

roles :admin, :manager, # coalfacer
        :student, :educator, :researcher, :ktp, :faculty_manager, :ip_asset_manager,  # for universities
        :sponsor, # for industry
        :project_manager, :representative, # for both uni and industry
        :grantor, :investor, :adviser, :innovation_consultant, :panel_member, # external
        :participant, :guest # public

  roles_attribute :roles_mask

In my ability.rb, I am trying to define the first ability, as:

   user ||= User.new # guest user (not logged in)

      #users who are not signed in can read publicly available projects

      can :read, Project, {:active => true, :closed => false,  &&  Project.sweep.disclosure.allusers: true}

In my Projects table, I have a boolean attribute called :closed.

I also have models for Sweep and Disclosure. The associations are:

Project.rb:
 has_one :sweep
  accepts_nested_attributes_for :sweep

Sweep. rb

belongs_to :project
has_one :disclosure
accepts_nested_attributes_for :disclosure

Disclosure.rb

belongs_to :sweep

My disclosures table has a boolean attribute called :allusers.

If Projects.closed is false AND project.sweep.disclosure.allusers is true, then I want to allow guests to read the Project.

When I try as I have set out above, I get an error which says:

undefined method `id' for nil:NilClass

It's referring to a line in my Project show view, which says:

<span class="editproject">    <% if current_user.id == @project.creator_id %>
          <%= link_to 'Edit Project', edit_project_path(@project) %> <% end %> </span>

Before trying to define abilities, this did not cause an error. Also, several of the projects returned in the index of projects are projects which do not meet the criteria I specified in my ability.rb (e.g. Disclosure.allusers is not set as true).

Can anyone see what I've done wrong in defining this ability as above?


Solution

  • The error is NoMethodError

    undefined method `id' for nil:NilClass
    

    As the error says, that Rails is trying to call current_user on nil:NilClass, which implies that your id object is nil.

    So, you should make current_user

    @current_user