是否可以使用 rolify gem for Rails 的回调跳过角色删除

Is it possible to skip role removing using callbacks with rolify gem for Rails

我在我的 Rails 应用程序中使用了 rolify,我试图通过回调停止进程“删除角色”,但它似乎没有按照我的要求进行。

rails 6.0.3 / rolify 5.3.0

这是我的代码

class User < ApplicationRecord
  rolify before_remove: :check_remove_role
  # ...
  def check_remove_role(role)
    puts 'Remove role'
    # Do not remove role if User is the only super_admin
    return false if role.name=='super_admin' && User.with_role(role.name).count == 1
  end
end

当我调用 user.remove_role(角色) 回调传递时,但即使回调 return 'false'.

,“删除过程”也不会停止

我的代码有问题吗?还是我必须用另一种方式来做(也许我不能为此使用回调)?

看来回调对您没有帮助。根据wiki


    Trying to remove a global role where the user has a role with the same name on a resource will remove that scoped role (whatever the scope is)
    Trying to remove a class scoped role where the user has an instance scoped role with the same name on a resource will remove that instance scoped role
    Trying to remove a role scoped to a resource class where the user has a global role won't remove it
    Trying to remove a role scoped to a resource instance where the user has a global role won't remove it

您似乎希望像使用 ActiveRecord 验证一样使用这些回调。它们是不同的东西。回调只是对角色记录前后运行代码的一种方式created/destroyed,并不用来控制里面的变异代码是否是运行.

部分选项:

  1. 向您的模型添加逻辑以测试它是否 can_remove_role?(:role),然后在进行更改之前在您的控制器中进行测试。
  2. 如果您从表单保存,您可以对模型进行验证以检查您的情况。 IE。如果那是更改的内容,则用户模型将无效。查看 Dirty 上的方法以获取有关如何查看 did/will 更改 https://api.rubyonrails.org/classes/ActiveModel/Dirty.html
  3. 的灵​​感
  4. 使用类似于 Pundit gem 或类似授权包(如果要在真实环境中使用,您的程序应该具有)的策略来包装角色的更改。 IE。在 Pundit 示例中,您的 UserPolicy 将有一个 change_role? 或类似的策略,您可以在其中定义 @record 的合法角色更改,然后对其调用授权。

选项 3 很好,因为它提供了一个 DRY 位置来制定更多关于用户可以做什么和不能做什么的规则。或许可以搜索有关如何一起使用 Pundit 和 Rolify 的教程。