使用 Rolify/Devise/Cancancan 与角色关联
Associations with Roles using Rolify/Devise/Cancancan
我在某处读到,使用 Rolify/Devise/Cancancan 是一种更好的替代方法,可以配置两个具有登录功能的设计模型(使用一个登录页面而不是两个)以及它们在其他模型之间的各自关联。我对如何在其中设置角色并仍然使用关联感到困惑。例如:
如果我使用了两个 Devise 模型,它们就会……
class Supervisor < ApplicationRecord
has_many :employees
end
class Employee < ApplicationRecord
belongs_to :supervisor
end
但是对于 Rolify,我想执行以下操作:
- 管理员 - 该用户应该能够设置其他用户的角色
- 主管-(该用户可以设置员工排班等)
- 员工
我做错了吗?我知道这个例子含糊不清,而且我似乎无法在任何地方找到关于如何设置角色关联的答案。
您要找的很可能是 self-referential association:
class AddSupervisorToUsers < ActiveRecord::Migration[6.1]
def change
add_reference :users, :supervisor,
null: true,
foreign_key: { to_table: :users }
end
end
class User < ApplicationRecord
belongs_to :supervisor,
class_name: 'User',
optional: true,
inverse_of: :employees
has_many :employees,
class_name: 'User',
foreign_key: :supervisor_id,
inverse_of: :supervisor
end
这基本上只是指向同一个 table 的关联。请注意,外键列必须可以为空,以避免出现先有鸡还是先有蛋的情况,这种情况会阻止您创建任何用户(如果 table 为空)。
虽然您可以通过以下方式使用 Rolify 执行此操作:
user.add_role(:supervisor, User.first) # add a role
User.with_role(:supervisor, User.first) # query for supervisors
这实际上并不等同,因为没有什么可以阻止多个用户成为一个用户的主管。您也没有外键来确保参照完整性,因为角色模型中的关联是多态的。
虽然 Rolify 对于某些用例来说是一个很好的工具,但您可能不想将所有业务逻辑都塞进去。
我在某处读到,使用 Rolify/Devise/Cancancan 是一种更好的替代方法,可以配置两个具有登录功能的设计模型(使用一个登录页面而不是两个)以及它们在其他模型之间的各自关联。我对如何在其中设置角色并仍然使用关联感到困惑。例如:
如果我使用了两个 Devise 模型,它们就会……
class Supervisor < ApplicationRecord
has_many :employees
end
class Employee < ApplicationRecord
belongs_to :supervisor
end
但是对于 Rolify,我想执行以下操作:
- 管理员 - 该用户应该能够设置其他用户的角色
- 主管-(该用户可以设置员工排班等)
- 员工
我做错了吗?我知道这个例子含糊不清,而且我似乎无法在任何地方找到关于如何设置角色关联的答案。
您要找的很可能是 self-referential association:
class AddSupervisorToUsers < ActiveRecord::Migration[6.1]
def change
add_reference :users, :supervisor,
null: true,
foreign_key: { to_table: :users }
end
end
class User < ApplicationRecord
belongs_to :supervisor,
class_name: 'User',
optional: true,
inverse_of: :employees
has_many :employees,
class_name: 'User',
foreign_key: :supervisor_id,
inverse_of: :supervisor
end
这基本上只是指向同一个 table 的关联。请注意,外键列必须可以为空,以避免出现先有鸡还是先有蛋的情况,这种情况会阻止您创建任何用户(如果 table 为空)。
虽然您可以通过以下方式使用 Rolify 执行此操作:
user.add_role(:supervisor, User.first) # add a role
User.with_role(:supervisor, User.first) # query for supervisors
这实际上并不等同,因为没有什么可以阻止多个用户成为一个用户的主管。您也没有外键来确保参照完整性,因为角色模型中的关联是多态的。
虽然 Rolify 对于某些用例来说是一个很好的工具,但您可能不想将所有业务逻辑都塞进去。