我在我的Rails应用中有大约13个模型,我在所有模型上使用了Ability。我的Ability类已经变得非常庞大了。不同的CRUD操作有不同的权限条件,这使得它很难进行管理。
有人可以指导我如何重构它吗?比如使用模块或类来使我的Ability类看起来更整洁。
我在我的Rails应用中有大约13个模型,我在所有模型上使用了Ability。我的Ability类已经变得非常庞大了。不同的CRUD操作有不同的权限条件,这使得它很难进行管理。
有人可以指导我如何重构它吗?比如使用模块或类来使我的Ability类看起来更整洁。
简单场景:如果你可以将权限分成几个互不相交的集合,那么你应该查看来自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
...
接下来的文件同理。
这里提到的解决方案中的一部分确实很吸引人。我想提出一种替代方法来处理这个问题,即我们在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