【问题标题】:Multiple abilities for resource with cancancancan 资源的多种能力
【发布时间】:2012-03-27 18:57:03
【问题描述】:

我正在尝试使用 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 和使用者执行 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 查询,其中包含一些奇怪的数据库架构,如果它尝试 INNER JOIN 消费者和员工表,你将一无所获。

有了一个块,我可能可以处理用户#show 的单个负载。但我不太确定如何更改此 sql 查询以允许我需要的内容,而不是一起跳过 load_resource 并在 users#index 代码中实现我自己的查询。

有什么建议吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 cancan


    【解决方案1】:

    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) 之一。

    【讨论】:

      【解决方案2】:

      所以这是我对自己问题的回答......我能找到的唯一可行的解​​决方案,但我无法想象这是一种有效的方法......

            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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-11
        • 2013-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多