2012-03-27 7 views
2

私はcancanでいくつかの認証を実装しようとしています。ユーザーは自分のユーザーアカウント、スタッフのユーザーアカウント、およびメンバーのユーザーアカウントを管理できます。このような何か: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 } 

は、残念ながら、私は動作しません。これを見つけたとき、認可コントローラのアクション、カンカンはINNERが効果的に戻ってから任意のクエリ結果を防ぎprovider_staffと消費者、上で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にしようとすると、

ブロックでは、おそらくusers#showの個々の読み込みを処理できます。しかし、私はこのSQLクエリをどのように変更して、load_resourceをすべてスキップし、ユーザ#インデックスコードで独自のクエリを実装するのが不十分であるかを知ることができます。

提案がありますか?

答えて

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 
0

カンカンはあなたの許可を処理する方法上の任意の制限を提示していません:ユーザがより良い方法で行うことができ、スタッフの一部である場合はもちろん

can manage, :User do |user| 
    staff_ids.include?(current_user.id) 
end 

チェック。理想的には何か:

if current_user.has_role? :staff 
    can manage, :User 
end 

そして、あなたはスタッフの一部のみを監視対象ユーザーに変更できることを必要とする場合:「CURRENT_USERはただ初期化(CURRENT_USER)一つです

if current_user.has_role? :staff 
    can manage, :User do |user| 
    current_user.id == user.supervisor_id 
    end 
end 

を。

関連する問題