是否可以使用cancan与两个能力类的能力

问题描述 投票:6回答:4

我使用的是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

从以上我的问题。

  1. 在cancan中是否可以实现多能力类,如果可以,那么如何创建它,因为我尝试了

    rails g cancan:user_ability

    但我得到的错误是 找不到生成器cancan:user_ability。.

  2. 如何为登录的UserAdmin选择合适的Ability类。

  3. 如果一个控制器同时被用户和管理员访问,那么如何获得当前登录的UserAdmin的对象。

还有其他的解决办法吗?

有谁能帮我解决这个问题?

ruby-on-rails ruby-on-rails-3 devise cancan
4个回答
12
投票

...也就是说,如果你愿意,你可以直接使用多个能力模型。

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

7
投票

你不需要多个能力类来实现。

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。


1
投票

我已经实现了部分的 @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

希望能帮到你


0
投票

我将对 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
© www.soinside.com 2019 - 2024. All rights reserved.