我使用的是rails 3.0.9,cancan 1.6.7和devise 1.4.8。
我使用两个devise模型(User和Admin)来实现不同的登录和注册流程。
所以我想根据登录用户(资源)来划分能力,因为有70多个模型,只有10个模型是两类用户通用的(这里有50多个模型和视图只有管理员用户使用)
我想实现两个能力类(UserAbility和AdminAbility),并且设计帮助方法current_usercurrent_admin应该传递给UserAbilityAdminAbility。
示例:在ApplicationController.rb文件中
在ApplicationController.rb文件中
def current_ability
if current_user
@current_ability = UserAbility.new(current_user)
elsif current_admin
@current_ability = AdminAbility.new(current_admin)
end
end
从以上我的问题。
在cancan中是否可以实现多能力类,如果可以,那么如何创建它,因为我尝试了
rails g cancan:user_ability
但我得到的错误是 找不到生成器cancan:user_ability。.
如何为登录的UserAdmin选择合适的Ability类。
如果一个控制器同时被用户和管理员访问,那么如何获得当前登录的UserAdmin的对象。
还有其他的解决办法吗?
有谁能帮我解决这个问题?
...也就是说,如果你愿意,你可以直接使用多个能力模型。
class UserAbility
include CanCan::Ability
def initialize(user)
can :read, :all
end
end
class AdminAbility
include CanCan::Ability
def initialize(admin)
can :manage, :all
end
end
class ApplicationController < ActionController::Base
# overriding CanCan::ControllerAdditions
def current_ability
if current_account.kind_of?(AdminUser)
@current_ability ||= AdminAbility.new(current_account)
else
@current_ability ||= UserAbility.new(current_account)
end
end
end
你不需要多个能力类来实现。
class Ability
include CanCan::Ability
def initialize(user_or_admin)
user_or_admin ||= User.new
common_rules(user_or_admin)
if user_or_admin.kind_of? Admin
admin_rules(user_or_admin)
else
user_rules(user_or_admin)
end
end
def common_rules(user_or_admin)
# can :verb, :noun
end
def admin_rules(admin)
can :manage, :all
end
def user_rules(user)
can :read, :all
end
end
CanCan最终会调用 Ability.new()
中的任何一个模型,但这完全没问题,因为你可以检查你收到的是什么样的对象。当然,如果你愿意,你也可以委托给其他对象;这一切都只是Ruby。
我已经实现了部分的 @willgiynn的 的解决方案,修改 current_ability
腻子 application_controller.rb.
在 能力.rb:
class UserAbility
include CanCan::Ability
def initialize(user)
can :read, :all
end
end
class AdminAbility
include CanCan::Ability
def initialize(admin)
can :manage, :all
end
end
在 application_controller.rb
def current_ability
@current_ability ||= current_admin ? AdminAbility.new(current_admin) : UserAbility.new(current_user)
end
希望能帮到你
我将对 willgiynn 已回答. 看来我必须再添加一些代码才能使它工作。我从下面找到了答案 岗位
增加以下内容: application_controller.rb
def current_ability
if admin_signed_in?
@current_ability ||= Ability.new(current_admin)
else
@current_ability ||= Ability.new(current_user)
end
end