一个网站一般都有后台管理功能,后台管理的人员分系统管理员和普通管理员,如果是论坛的话,前台又有好几个角色,版主,总版主,VIP用户,认证用户等等,如果自己去重新去设计的话费时不说可能还不到位,最好有插件,简单配置一下,就可以用了,gem的设计也是出于这个理念,google了一番,CanCan用得比较多,就用这个吧。
1.安装CanCan,编辑Gemfile
执行
$ bundle install
$ rails generate
...
Cancan:
cancan:ability
...
2.定义Ability类
$ rails g cancan:ability
create app/models/ability.rb
#app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
# Define abilities for the passed in user here. For example:
#
# user ||= User.new # guest user (not logged in)
# if user.admin?
# can :manage, :all
# else
# can :read, :all
# end
#
# The first argument to `can` is the action you are giving the user permission to do.
# If you pass :manage it will apply to every action. Other common actions here are
# :read, :create, :update and :destroy.
#
# The second argument is the resource the user can perform the action on. If you pass
# :all it will apply to every resource. Otherwise pass a Ruby class of the resource.
#
# The third argument is an optional hash of conditions to further filter the objects.
# For example, here the user can only update published articles.
#
# can :update, Article, :published => true
#
# See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
end
end
3.创建Role model
4.User和Role之间添加关联
class User
include Mongoid::Document
...
embeds_many :roles
...
end
class Role
include Mongoid::Document
field :name
embedded_in :user
end
5.在User类中添加role?函数
def role?(role)
return !!self.roles.where({"name" => /#{role.to_s}/}).first
end
6.编辑app/models/ability.rb文件
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
if user.role? :admin
can :manage, :all
elsif user.role? :user
can :read, Forum
end
end
end
7.编辑需要添加权限的controller
class ForumsController < ApplicationController
before_filter :authenticate_user!
#load_and_authorize_resource 和 authorize_resource 两个方法都可以,不同的是load_and_authorize_resource会先加载本类model的值
authorize_resource
def index
@forums = Forum.all()
#authorize! :read, @forums 对单个action进行权限判断
end
def new
@forum = Forum.new
end
end
也可以在view中进行权限判断,方法是can? 和 cannot?
# app/views/forums/index.html.haml
- if can? :create, @forums
= link_to "创建", new_forum_path
8.处理未授权的访问的方法
如果权限认证失败,cancan会抛出一个CanCan::AccessDenied的异常,你可以在ApplicationController中捕获它来显示自己内容。
class ApplicationController < ActionController::Base
...
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_url, :alert => exception.message
end
...
end