Question

I am using CanCan and have been researching how to get started. However, it seems that most of the tutorials aren't very specific, and don't suit my own needs. I'm building a social network where users can create projects and add other users to their projects, allowing those users to moderate that project.

I currently have a Role model with a string attribute, and a User model from devise. Where do I go from here?

I have seen this post, but it doesn't fully explain how to set up the roles and the relationship between the Role model and the ability.rb file from CanCan.

If you need me to be more specific, please say so! I'm not the greatest Rails developer ;)

Edit

I have seen the railscast on this, and it doesn't have a separate Role model which I would like to have. I have tried using Rolify, but people have said it is too complicated and that it's possible to do it in a more simple way. I also ran into some complications so I'd like to just use my own Role model.

Edit

I'm currently using rolify and the roles are working. I found my solution at: https://github.com/EppO/rolify/wiki/Tutorial

Was it helpful?

Solution

If your User-Role stuff is looking similar to following:

class User < ActiveRecord::Base
  has_many :user_roles
  has_many :roles, :through => :user_roles

  # user model has for example following attributes:
  # username, email, password, ...
end

class Role < ActiveRecord::Base
  has_many :user_roles
  has_many :users, :through => :user_roles

  # role model has for example following attributes:
  # name (e.g. Role.first.name => "admin" or "editor" or "whatever"
end

class UserRole < ActiveRecord::Base
  belongs_to :user
  belongs_to :role
end

you can do following:

First, extend your User model with a few helper methods or something similar:

class User < ActiveRecord::Base

  def is_admin?
    is_type?("admin")
  end

  def is_editor?
    is_type?("editor")
  end

  def is_whatever?
    is_type?("whatever")
  end

  private

  def is_type? type
    self.roles.map(&:name).include?(type) ? true : false # will return true if the param type is included in the user´s role´s names. 
  end

end

Second, extend your ability class:

class Ability
  include CanCan::Ability

  def initialize(user)
    if user
      can :manage, :all if user.is_admin?
      can :create, Project if user.is_editor?
      can :read, Project if user.is_whatever?
      # .. and so on..
      # you can work with your different roles on base of the given user instance.
    end
  end
end

Alternatively you could remove your User-Roles has-many-through associations and replace it with the easy-roles gem - very useful. It is available on github: https://github.com/platform45/easy_roles

Now you should have an idea how you could work with cancan, roles and all the stuff together :-).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top