I’m trying to implement some authorization with cancan where a user will have the ability to manage their own user account, their staff’s user account and their member’s user accounts. Something like this:
# 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 }
Unfortunately I’ve found this does not work when authorization a controller action, because cancan performs an INNER JOIN on provider_staff and consumer, which effectively prevents any query results from returning:
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
Sorry that’s an ugly MSSQL query with some funk for a weird database schema, point being if it tries to INNER JOIN both the consumer and staff tables you get nothing.
With a block I can probably handle the individual load for say users#show. But I’m not quite sure how I can get this sql query changed to allow what I need, short of skipping load_resource alltogether and implementing my own query in the users#index code.
Any suggestions?
So here’s my answer to my own question… The only solution I can find that works, yet I cannot possibly imagine this is an efficient way to do this…