Rails:使用CanCan根据单个模型的实例定义多个角色?

kib*_*ekr 7 ruby authorization ruby-on-rails cancan

我目前仍然坚持如何根据我们想要的每个条件来分离CanCan的角色.在我们的应用程序中,有许多类别(如数学,英语,历史等),每个类别都有很多课程.

每个用户可以在每个类别上拥有许多不同的角色.例如,John可以成为数学的"读者",这意味着他可以阅读所有数学课程.约翰也可以成为英语的"作家",这意味着他可以阅读所有英语课程,在英语类别中创建课程,只编辑/删除他在英语中创建的课程.

如果这些是约翰所拥有的唯一角色,他将无法在导航栏中看到类别历史记录,并且将无法访问历史记录中的课程.

这些是建立关系的方式:

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
Run Code Online (Sandbox Code Playgroud)

在model/ability.rb中我们有

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
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 我们如何以正确的方式分离"读者"和"作家"的角色?我们如何访问我们可以访问的类别中的课程?

  2. 在ability.rb中定义reader和writer方法之后,我们如何在视图页面中使用它们?看起来当前的文档使用类似"<%if can can ?:read,@ category%>"但不使用我们分离和定义的方法.

ps我们将有7个不同的角色:访客,读者,作家,编辑,经理,管理员和app_admin(我们的开发人员)

我一直试图解决这个问题3天 - 请理解我还是一个相当初学者!提前致谢

Sam*_*ami -2

在你的 gemfile 中包含。

  1. 宝石“康康”

  2. 安装捆绑包。

  3. Rails g 康康舞:能力

这将在您的模型中生成一个能力类别。

如下定义您的能力。

但请记住,您已经定义了角色,

比如你有一个 User 模型,

定义了两个角色,即管理和支持。

  class Ability
      include CanCan::Ability
       def initialize(user)
         user||= User.new
           can :read, :all
       if user.role == 'admin'
          can :manage, :all
       else
          can :read, :all
          end
       end
    end
Run Code Online (Sandbox Code Playgroud)

4. 对于要限制用户的资源,请在其控制器中使用以下过滤器。

              load_and_authorize_resource
Run Code Online (Sandbox Code Playgroud)

5. 如果您想限制视图中的某些内容不显示。

    <% if can? :manage, @flower %>
     <td><%= link_to 'Edit', edit_flower_path(flower) %></td>
    <% end %>
    <% if can? :manage, @flower %>
      <td><%= link_to 'Destroy', flower_path(flower), method: :delete, data: { confirm: 'Are you sure?' } %></td>
    <% end %>
Run Code Online (Sandbox Code Playgroud)