我对rails(3)比较陌生,正在构建一个使用CanCan的应用程序,其中有3层用户。
我的能力现在是bog-stock,从cancan docs复制,基本上定义了guest角色和admin角色
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # Guest user
if user.is_admin?
can :manage, :all
else
can :read, [Asana,Image,User,Video,Sequence]
end
end
end
我想添加用户角色。由于我正在创建那个一次性用户模型,我想过使用new_record?确定用户是否已登录。类似的东西:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # Guest user
if !user.new_record? and user.is_admin?
can :manage, :all
elsif !user.new_record? and !user.is_admin?
can {registered user-y permissions}
else
can :read, [Asana,Image,User,Video,Sequence]
end
end
end
但是,感觉不对。似乎与实际登录相似,并且担心其实际上是否安全。
以更优雅的方式寻求建议。
谢谢!
答案 0 :(得分:21)
好问题,我使用较低到较高权限的方法:
class Ability
include CanCan::Ability
def initialize(user)
# Guest User
unless user
can :read, [Asana,Image,User,Video,Sequence]
else
# All registered users
can {registered user-y permissions}
# Admins
if user.is_admin?
can :manage, :all
end
end
end
end
这样一来,如果明天你还有其他角色可以集成,你可以这样添加一个case语句:
class Ability
include CanCan::Ability
def initialize(user)
# Guest User
unless user
can :read, [Asana,Image,User,Video,Sequence]
else
# All registered users
can {registered user-y permissions}
# Different roles
case user.role
when 'admin'
can :manage, :all
when 'manager'
can :manage, [Video, Image, Sequence]
end
end
end
end
答案 1 :(得分:2)
那么你基本上想要的是没有登录用户的能力,登录用户的能力以及登录管理员的能力?
因为当前用户模型被传递到初始化,所以你将不得不根据用户的属性进行测试,并且使用存储在用户模型上的基本角色属性是有意义的,例如
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role == 'admin'
# Admin roles
can :manage, :all
elsif user.role == 'user'
# Signed in user permissions
else
# Guest permissions
can :read, :all
end
端
因此,当用户注册/注册时,您可以将角色值默认为“user”,然后允许某些方法在管理界面中将其更新为“admin”。你可以使用一个管理员吗?检查用户,因为这对于访客和普通登录用户来说都是错误的。
答案 2 :(得分:1)
如果用户对象不是new_record,则表示它存储在数据库中。对我来说,足以接受它是一个登录用户。
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
# Guest users
can :create, User
# Members
unless user.new_record?
can [:edit, :update], User, :id => user.id
end
# Admins
if user.admin?
can :manage, :all
end
end
end
此外,有时管理功能不一定非常花哨 - 也许这就是你需要的全部内容?
class User < ActiveRecord::Base
# Alternatively, you can add an admin attribute flag
def admin?
["theadmin@yourservice.com", "hisspouse.yourservice.com"].include?(email)
end
end
最后,虽然您不熟悉rails,但我建议您从头开始编写自己的身份验证。使用像Devise和Authlogic这样的宝石似乎总是有它的缺点。它并不一定非常复杂。 Ryan(康康的作者)对这个主题进行了精彩的截屏:http://railscasts.com/episodes/250-authentication-from-scratch
答案 3 :(得分:0)
如果您确实拥有持久用户模型,那么这是一个登录用户,否则他们是访客。也许你过分思考这个?
class Ability
include CanCan::Ability
def initialize(user=nil)
if user && user.is_admin?
can :manage, :all
elsif user
can {registered user-y permissions}
else # guest
can :read, [Asana,Image,User,Video,Sequence]
end
end
end
答案 4 :(得分:0)
如果使用角色继承,则此模式运行良好:
user ||= User::GUEST # guest user (not logged in)
# anyone
can [:read], Post
# any registered user
if user.role? :user
can [:comment], Post
end
# editor
if user.role? :editor
can [:create], Post
end
# admin
if user.role? :admin
can [:manage], Post
end
GUEST = User.new.tap {|u| u.role = 'guest'}
ROLES = %w[guest user editor admin]
def role?(base_role)
begin
ROLES.index(base_role.to_s) <= ROLES.index(role.to_s)
rescue
raise "invalid role query '#{base_role}' against user role '#{role}'"
end
end