CANCAN => Admin + Agent + User

2019-09-21 04:30发布

问题:

Need Help! :)


Use Case: Admin can create another admin when he have role of "SuperAdmin", Admin Can also Create "Agents"

Roles for Admin Model:

  1. SuperAdmin
  2. Admin

Admin can create both the roles can create "Agents"


Agent can create "User" but he will not be able to create "Agents" and he should not see users created by other Agents. He has only one Role - "Agent"


Now the problem is : how to initialize "admin", "agent" & "user" in Ability as they are are 3 different models ?

class Ability
  def initialize(user)
    user ||= User.new # guest user (not logged in)
    can :read, Photo, Photo.unowned do |photo|
      photo.groups.empty?
    end
  end
end

Note: Users are under Agent and Agents are under Admin.. I need them to be different models

回答1:

Well, I suggest you define your role in a base model like 'User'. Then use this to create a user hierarchy. Your model should initialize the role. Say you create a User, then the role should be something like :user. Any user that tries to perform an action will (if your controller is well defined) go through 'initialize'.

The initialize method is not to initialize the role but the rules for that particular role.

class Ability
   def initialize(user)
      user ||= User.new # guest user (not logged in)

      if user.role == :admin
         can :read, Photo, Photo.unowned do |photo|
           photo.groups.empty?
      elsif user.role == :agent 
         # rules for agents
      else
         # rules for others
      end
  end
end


回答2:

What you need is nested attributes, which will allow you to have a single User model with separate models for each type of user (if your various roles differ a lot in the types of information they require, that is). For example, agents might have education, field or region, and personal website attributes while normal users have company, favorite quote, and whatever else.

The User model would have information all roles require (email, password, name, role) while models for each role would have information specific to that role. This way, you can follow the documentation for CanCan to do your authorization, but still have role-specific information.

There is a great railscast on nested_attributes: http://railscasts.com/episodes/196-nested-model-form-part-1 (part 1) and http://railscasts.com/episodes/197-nested-model-form-part-2

Note: These railscast episodes are specific to making question and answer functionality, but the concepts they teach can apply directly to your situation.