ruby-on-rails 使用CanCanCan,如何授权控制器中的任一/或?

xzv2uavs  于 2023-02-01  发布在  Ruby
关注(0)|答案(2)|浏览(138)

我有一个用于管理多个对象(如用户和组)的页面,我希望确保只有有权创建至少一个此类对象的用户才能查看该页面。
基本上,我希望能够写出这样的东西

(authorize! :create, User) || (authorize! :create, Group)

有什么建议吗?

vyswwuz2

vyswwuz21#

实现这一点的一种方法是通过混合

load_and_authorize_resource :user
load_and_authorize_resource :through => :user

这是一个在控制器的所有资源上调用authorize的方便助手,它可以执行如下操作:

class GroupsController < ActionController::Base
  load_and_authorize_resource
  load_and_authorize_resource :through => :user

  def create
    # Automatically does the following:
    # @group = Group.find(group_params[:id])
    # authorize! :create, @group

    # @user= User.find(group_params[:user_id])
    # authorize! :create, @user
  end

end

因此,在控制器中加载组和用户对象的位置,它将根据您的规则/功能自动授权它们,例如

can [:create], [User, Group]

当然,您需要将组作为嵌套资源:

resources :users do
  resources :groups
end

希望有帮助。

tf7tbtn2

tf7tbtn22#

我能想到的最好的方法是使用多个can?语句,并在失败时引发AccessDenied。您还应该避免对模型类进行授权检查,而是对模型示例进行授权。请参阅CanCanCan -常见错误。

user = User.new(...)
group = Group.new(...)
raise CanCan::AccessDenied.new(nil, :create, [user, group]) \
  unless can?(:create, user) || can?(:create, group)

AccessDenied.new(nil ,..)-〉nil获取默认错误消息中的第一个参数结果。
我可能会将其移到名为def authorize create_group_or_user!的方法的帮助器中
也就是说,也许您在此控制器中做的太多了?或者,您可以使此控制器 * 未经授权 * 重定向到相应的GroupControllerUserController,并在这些位置执行相应的授权检查。
备选方案2:也许对内容使用accessible_by限制,并且根本不要调用authorize!

相关问题