I'm currently stuck on how to separate roles for CanCan depending on each condition that we want. In our application, there are many categories (such as math, english, history, etc.) and within each are many courses.
Each user can have many different roles on each category. For example, John can be a "reader" for math, which means he can read all the courses that are in math. John can also be a "writer" for english, which means he can read all the courses in english, create a course within category english, and edit/delete only the courses he created within english.
If these were the only roles John had, he would not be able to see the category history in the navbar, and would be denied access to courses that are within history.
These are how relations are set up:
class User < ActiveRecord::Base
has_many :roles
def has_role?(role_sym)
roles.any? { |r| r.level.underscore.to_sym == role_sym }
end
end
class Category < ActiveRecord::Base
has_many :roles
has_many :courses
end
class Role < ActiveRecord::Base
belongs_to :user
belongs_to :category
attr_accessible :level, :category_id, :user_id
end
in model/ability.rb we have
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in) #guest
if user.has_role? :reader
reader(user)
end
if user.has_role? :writer
writer(user)
end
end
#BE ABLE TO SEE COURSES AND CATS FOR PERMITTED CATS.
def reader(user)
can :read, Category, :roles => { :user_id => user.id, :level => "reader" }
## how would we be able to limit reading of courses that are within permitted categories? something like category.courses ~~
end
def writer(user)
reader(user) #inheriting from reader? this doesnt work because level is hardcoded into reader
can :read, Category, :roles => { :user_id => user.id, :level => "writer"}
# 1.you can read all courses in category that you are given permission to
# 2.you can write courses in permitted category
# 3.you can edit, delete courses that only youve created within permitted category
end
end
Questions:
How do we separate the roles of "reader" and "writer" in the correct way? How do we access the courses that are within the categories that we have access to?
After defining the reader and writer methods in the ability.rb, how do we use them in our view pages? It looks like the current documentations use something like "<% if can? :read, @category %> " but that doesn't use the methods we separated and defined.
p.s. We will have 7 different roles: guest, reader, writer, editor, manager, admin, and app_admin(our developers)
I've been trying to solve this for 3 days now - please understand that I'm still fairly a beginner! Thanks in advance