权限控制[2] CanCan + Rolify + Devise

来源:互联网 发布:java.util.scanner错误 编辑:程序博客网 时间:2024/05/23 18:53

在model/ability.rb中定义权限

Reference: Defining Abilities
基础权限

class Ability  include CanCan::Ability  def initialize(user)    user ||= User.new # guest user (not logged in)    if user.admin?      can :manage, :all    else      can :read, :all    end  endend

自定义权限集合

def initialize(user)  user ||= User.new  alias_action :create, :read, :update, :destroy, to: :crud  can :crud, User  can :invite, Userend

利用Hash条件筛选定义

class Photo  has_and_belongs_to_many :groups  scope :unowned, includes(:groups).where(groups: { id: nil })endclass Group  has_and_belongs_to_many :photosendclass Ability  def initialize(user)    user ||= User.new # guest user (not logged in)    can :read, Photo, Photo.unowned do |photo|      photo.groups.empty?    end  endend

利用代码块来定义权限

Reference: Defining Abilities with Blocks

can :update, Project do |project|  project.priority < 3end

重写默认方法

Reference: Changing Defaults
利用cancancan+rolify+devise做权限控制,如果你使用的是自己建的表,名字有区别,可能会导致current_user无法正常使用。比方说,项目中的用户表是buser,那么用device之后,当前用户就应该是current_buser,且需要重写cancancan的默认加载方法。
直接把方法写在ApplicaitonController中即可。

CanCanCan makes two assumptions about your application.You have an Ability class which defines the permissions.You have a current_user method in the controller which returns the current user model.You can override both of these by defining the current_ability method in your ApplicationController. The current method looks like this.def current_ability  @current_ability ||= Ability.new(current_user)endThe Ability class and current_user method can easily be changed to something else.# in ApplicationControllerdef current_ability  @current_ability ||= AccountAbility.new(current_account)end

Restful Controller中的权限控制

Reference:
- Authorizing controller actions
- rails基于devise+cancancan+rolify的简单权限控制实现
在controller中做权限控制,你可以控制整个controller,也可以逐个方法做局部控制。
针对有对应资源的controller,只需要在开头加上控制语句即可。

You can use the authorize! method to manually handle authorization in a controller action. This will raise a CanCan::AccessDenied exception when the user does not have permission. See Exception Handling for how to react to this.def show  @project = Project.find(params[:project])  authorize! :show, @projectendHowever that can be tedious to apply to each action. Instead you can use the load_and_authorize_resource method in your controller to load the resource into an instance variable and authorize it automatically for every action in that controller.class ProductsController < ActionController::Base  load_and_authorize_resourceendThis is the same as calling load_resource and authorize_resource because they are two separate steps and you can choose to use one or the other.class ProductsController < ActionController::Base  load_resource  authorize_resourceend

针对没有对应资源的controller,我们也可以为它指定需要加载的类。

class LogController < ApplicationControlle    load_and_authorize_resource :class => "Production"      def record_log        ........      end

NonRestful Controller中的权限控制

Reference:Non RESTful Controllers
针对部分controller与资源不挂钩的情况,我们也可以进行单独控制。
注意,此时我们只能只能进行逐个方法的局部控制,不能统一控制controller。
在定义权限的时候,注意两个参数必须都是ruby的符号对象。

For example, let's say we have a controller which does some miscellaneous administration tasks such as rolling log files. We can use the authorize! method here.class AdminController < ActionController::Base  def roll_logs    authorize! :roll, :logs    # roll the logs here  endendAnd then authorize that in the Ability class.can :roll, :logs if user.admin?Notice you can pass a symbol as the second argument to both authorize! and can. It doesn't have to be a model class or instance. Generally the first argument is the "action" one is trying to perform and the second argument is the "subject" the action is being performed on. It can be anything.

页面的权限控制

Reference:Checing Ablities
当我们在model/ablitiy.rb中定义完所有权限之后,我们可以在页面上直接使用。

<% if can? :create, Project %>  <%= link_to "New Project", new_project_path %><% end %>
原创粉丝点击