我正在尝试使用cancan实施一些授权,用户可以在其中管理自己的用户帐户,其员工的用户帐户及其成员的用户帐户。像这样:
# own account
can :manage, User, :ID => user.ID
# staff
can :manage, User, :provider_staff => {:ProviderID => user.ID}
#members
can :manage, User, :consumer => { :ProviderID => user.ID }
不幸的是,我发现在授权控制器操作时这不起作用,因为cancan在provider_staff和consumer上执行INNER JOIN,这有效地阻止了任何查询结果的返回:
SELECT TOP (10) [__rnt].ID FROM ( SELECT ROW_NUMBER() OVER (ORDER BY [User].UserDisplayAs ASC) AS [__rn], [User].ID FROM [User] INNER JOIN [Consumer] ON [Consumer].[ID] = [User].[ID] INNER JOIN [ProviderStaff] ON [ProviderStaff].[ID] = [User].[ID] LEFT OUTER JOIN [UserView] ON [UserView].[ID] = [User].[ID] LEFT OUTER JOIN [Address] ON [Address].[UserID] = [User].[ID] LEFT OUTER JOIN [Phone] ON [Phone].[ID] = [User].[PhoneID] WHERE [User].[DeletedFlag] = 0 AND (([Consumer].[ProviderID] = 32) OR (([ProviderStaff].[ProviderID] = 32) OR ([User].[ID] = 32))) AND (UserView.IsConsumer = 1) GROUP BY [User].ID, [User].UserDisplayAs ) AS [__rnt] WHERE [__rnt].[__rn] > (0) ORDER BY [__rnt].[__rn] ASC
很抱歉这是一个丑陋的MSSQL查询,对于一个奇怪的数据库模式有一些恐惧,如果它试图在内部加入消费者和员工表,你什么也得不到。
使用块我可以处理个人负载,例如用户#show。但是我不太确定如何将这个sql查询更改为允许我需要的东西,除了完全跳过load_resource并在用户#index code中实现我自己的查询。
有什么建议吗?
答案 0 :(得分:0)
CanCan对您处理权限的方式没有任何限制:
can manage, :User do |user|
staff_ids.include?(current_user.id)
end
当然,检查用户是否是员工的一部分可以以更好的方式完成。理想情况如下:
if current_user.has_role? :staff
can manage, :User
end
如果您需要,部分员工只能更改受监管用户:
if current_user.has_role? :staff
can manage, :User do |user|
current_user.id == user.supervisor_id
end
end
其中'current_user'只是 initialize(current_user)。
答案 1 :(得分:0)
所以这是我对自己问题的回答......我能找到的唯一解决方案是有效的,但我无法想象这是一种有效的方法......
can :manage, User, ["( [User].[ID] IN (SELECT [ID] FROM [ProviderStaff] WHERE ProviderID = ?) OR [User].[ID] IN (SELECT [ID] FROM [Consumer] WHERE ProviderID = ?) )", user.ID, user.ID] do |u|
if !u.consumer.nil?
u.consumer.ProviderID == user.ID
elsif !u.provider_staff.nil?
u.provider_staff.ProviderID == user.ID
end
end