gpt4 book ai didi

ruby-on-rails-3.2 - Rolify remove_role 从角色表中删除?

转载 作者:行者123 更新时间:2023-12-02 07:36:07 26 4
gpt4 key购买 nike

这很奇怪。我在 Rails 3.2 应用程序中使用 Rolify + CanCan + Devise。我的用例很简单。我希望一个用户一次只有一个角色,因此要更改角色,我会执行以下操作:

user.remove_role "admin"
user.add_role "associate"

对我来说奇怪的是,当我这样做时,角色“admin”会从角色表中删除。为什么会这样呢?我不想完全消除该角色,只想消除用户的给定角色。我做错了什么?

这是 SQL。请注意最后一条从角色中删除的语句:

3] pry(main)> u.remove_role "sub_admin"
Role Load (0.1ms) SELECT "roles".* FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = 2 AND "roles"."name" = 'sub_admin'
(0.0ms) begin transaction
(0.3ms) DELETE FROM "users_roles" WHERE "users_roles"."user_id" = 2 AND "users_roles"."role_id" IN (2)
(1.9ms) commit transaction
User Load (0.1ms) SELECT "users".* FROM "users" INNER JOIN "users_roles" ON "users"."id" = "users_roles"."user_id" WHERE "users_roles"."role_id" = 2
(0.0ms) begin transaction
SQL (2.1ms) DELETE FROM "roles" WHERE "roles"."id" = ? [["id", 2]]
(0.6ms) commit transaction

最佳答案

基本问题是角色名称、资源类型和资源 ID 的每个组合仅在 roles 表中存储一次。如果您删除该行,那么所有人都会删除该行。

解决方案是仅删除连接 UserRole 模型的 rolify 的 join 表 中的行。为了便于访问,我将使连接表成为一个模型,以使用一些 Rails 魔法来生成 SQL。由于这确实是一种服务对象,因此我将其设为单例类。这是我的技巧:

class UsersRoles < ActiveRecord::Base

def self.delete_role(subject,role_symbol, obj=nil)
res_name = obj.nil? ? nil : obj.class.name
res_id = obj.id rescue nil
role_row = subject.roles.where(name: role_symbol.to_s, resource_type: res_name , resource_id: res_id).first
if role_row.nil?
raise "cannot delete nonexisting role on subject"
end
role_id = role_row.id
self.delete_all(user_id: subject.id,role_id: role_id)
end

private_class_method :new
end

此代码尚未优化,但应该让您知道该怎么做:例如,您现在可以向 User 模型添加一个便捷方法:

def delete_role(role_symbol,target=nil)
UsersRoles.delete_role self,role_symbol,target
end

然后你可以说:

user.delete_role :admin

它只会删除您想要的内容。

请注意,此不会删除具有该角色的表行,我将保留该行以供将来使用。

关于ruby-on-rails-3.2 - Rolify remove_role 从角色表中删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20076707/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com