扶手:使用惨惨定义多个角色,这取决于单一模型的实例? [英] Rails: Using CanCan to define multiple roles depending on instances of single Model?

查看:163
本文介绍了扶手:使用惨惨定义多个角色,这取决于单一模型的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前停留在如何为惨惨取决于我们希望每个条件分隔作用。
在我们的应用中,也有很多类别(如数学,英语,历史等),并在每个有许多课程。

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.

这些关系是如何设置:

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

在模型/ ability.rb我们有

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

问题:


  1. 我们如何以正确的方式分开读者和作家的角色?我们如何访问是我们能够获得的类别内的课程?

  1. 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?

定义在ability.rb读取器和写入方法后,我们如何使用它们,我们认为网页?它看起来像当前的单证使用类似&LT;若能%:阅读,@Category%>
但是,这并不使用我们分开,定义的方法。

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。我们将有7个不同的角色:来宾,读者,作家,编辑,经理,管理和app_admin(我们的开发人员)

p.s. We will have 7 different roles: guest, reader, writer, editor, manager, admin, and app_admin(our developers)

我一直在试图解决这个对于现在是3天 - 请理解,我还是相当初学者!在此先感谢

I've been trying to solve this for 3 days now - please understand that I'm still fairly a beginner! Thanks in advance

推荐答案

我遇到了一个同样的需求今天发现了一个办法做到这一点上的惨惨维基

I ran into a same needs today and found a way to do this on CanCan Wiki.

简单遵循这些简单的步骤:

Simple follow these simple steps:

1)与你的角色名创建User类下一个常数:

1) Create a constant under the User class with your role names:

class User < ActiveRecord::Base
  ROLES = %w[admin moderator author banned]
end

2A)创建,如果你正在使用的ActiveRecord运行迁移:

2a) Create and run a migration if you are using ActiveRecord:

rails generate migration add_roles_mask_to_users roles_mask:integer
rake db:migrate

2B)上的用户模型添加这些领域,如果你使用的是Mongoid:

2b) Add these field on User model if you are using Mongoid:

field :roles_mask, type: Integer

3)下一步,你需要以下code添加到用户模式:

3) Next you'll need to add the following code to the User model:

# in models/user.rb
def roles=(roles)
  self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
end

def roles
  ROLES.reject do |r|
    ((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero?
  end
end

4)如果你使用的设计没有强有力的参数,不要忘了添加attr_accessible:角色对你的用户模型。如果您使用的是与strong_parameters设计,无论是作为在Rails 3应用程序宝石,或者是内置在Rails中4,不要忘记给角色添加到允许列表中的控制器:

4) If you're using devise without strong parameters, don't forget to add attr_accessible :roles to you user model. If you're using devise with strong_parameters, either as a gem in a Rails 3 app, or as is built-in in Rails 4, dont forget to add the roles to the permitted list in the controller:

class ApplicationController < ActionController::Base
  before_filter :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, roles: [])}
  end
end

5)增加code波纹管生成视图中的复选框来设置这些角色:

5) Add the code bellow to generate checkboxes in the view for setting these roles:

<% for role in User::ROLES %>
  <%= check_box_tag "user[roles][#{role}]", role, @user.roles.include?(role), {:name => "user[roles][]"}%>
  <%= label_tag "user_roles_#{role}", role.humanize %><br />
<% end %>
<%= hidden_field_tag "user[roles][]", "" %>

6)最后,你可以再增加一个方便的方法来检查能力类用户的角色:

6) Finally, you can then add a convenient way to check the user's roles in the Ability class:

# in models/user.rb
def is?(role)
  roles.include?(role.to_s)
end

# in models/ability.rb
can :manage, :all if user.is? :admin

这就是它。

我希望这可以帮助。

这篇关于扶手:使用惨惨定义多个角色,这取决于单一模型的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆