Rails CanCan宝石重构Ability类

11

我在我的Rails应用中有大约13个模型,我在所有模型上使用了Ability。我的Ability类已经变得非常庞大了。不同的CRUD操作有不同的权限条件,这使得它很难进行管理。

有人可以指导我如何重构它吗?比如使用模块或类来使我的Ability类看起来更整洁。

3个回答

18

简单场景:如果你可以将权限分成几个互不相交的集合,那么你应该查看来自CanCan创建者@ryanb的这个提案,他将能力拆分为几个不同的类,然后覆盖ApplicationController中的current_ability方法。

如何在 CanCan 中拆分大型 Ability 类 - Gists

更复杂的场景:如果你有多个不同的重叠权限集合,你可以尝试这种方法:

# app/models/ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    self.merge Abilities::Everyone.new(user)

    if user
      self.merge Abilities::Admin.new(user) if user.admin?
      self.merge Abilities::Authenticated.new(user)
    else
      self.merge Abilities::Guest.new(user)
    end
  end
end

# app/models/abilities/admin.rb
module Abilities
  class Admin
    include CanCan::Ability

    def initialize(user)
      # define abilities here ...
    end
  end
end

# app/models/abilities/everyone.rb
...

接下来的文件同理。


3

这里提到的解决方案中的一部分确实很吸引人。我想提出一种替代方法来处理这个问题,即我们在application_controller中覆盖current_ability方法,使其根据所使用的控制器进行动态处理。从那里,我们可以在每个控制器中指定要使用的能力。它可能看起来像这样:

./app/abilities
              ./posts_ability.rb
              ./comments_ability.rb
              ./admin_ability.rb
              ./pictures_ability.rb
              ./uploads_ability.rb

然后在./app/controllers/my_controller.rb中,它会像这样:

class MyController < ApplicationController
    authorize_with PostsAbility
end

它也可能自动化,即PostsController默认使用PostsAbility。回顾一下,有一件事需要考虑。似乎有两种尝试扩展能力的方式。一种是我们可能有许多“角色”,可以以不同的方式与数据进行交互。另一种方式是我们有许多模型,并且需要一种将逻辑分割开的方法。这种方法非常适合它们,因为您可以根据正在执行(或可能要执行)的操作来拆分逻辑。还有一件事,我们还可以使用继承来预加载相互依赖的功能。如果Comment属于Post,则CommentsAbility可以从PostsAbility继承以添加所需的逻辑。

-2
你可以将能力类简单地移植到数据库中,管理所有权限,并在检查当前用户执行操作的能力之前提取。将权限移到数据库中不会花费太多时间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接