2016-09-21 42 views
0

我是新來的專家,並試圖提出處理索引操作的嵌套資源的最佳方法。我找到了similar question,但它不處理管理員權限,我只是不確定我的解決方案是否完全正確。擁有嵌套資源的專家的管理員權限以及如何處理索引操作

比方說,我有兩個模型,一個User可以有很多筆記和一個Note屬於一個用戶。用戶不能查看來自其他用戶的筆記,除非他們是管理員。同時,管理員能夠創建他們自己的筆記,因此還必須能夠通過他們自己的索引操作來檢索他們的列表。

routes.rb中

resources :users, only: :show do 
    resources :notes 
end 

notes_controller.rb

class NotesController < ApplicationController 

    #would probably move to application_controller.rb 
    after_action :verify_authorized 
    after_action :verify_policy_scoped 

    def index 
    user = User.find(params[:user_id]) 
    @notes = policy_scope(user.notes) 
    authorize user 
    end 

    #additional code 
end 

note_policy.rb

class NotePolicy < ApplicationPolicy 

    class Scope < Scope 
    def resolve 
     if user.admin? && scope != user.notes 
     scope 
     else 
     user.notes 
     end 
    end 
    end 

    #additional code 
end 

user_policy.rb

class UserPolicy < ApplicationPolicy 

    def index? 
    user == record || user.admin? 
    end 

    #additional code 
end 

回答

0

你是它得太多:這裏

class NotePolicy < ApplicationPolicy 

    class Scope < Scope 
    def resolve 
     scope.where(user: user) 
    end 
    end 

    def index? 
    record == user || user.admin? 
    end 

    # ... 
end 

注意,它從範圍一個好主意,鏈正在從policy_scope通過。它可以讓你的控制器設置任何與授權無關的範圍,例如分頁。

也在index?我們有點作弊。我們只是傳遞用戶,而不是傳遞一個筆記實例。

class NotesController < ApplicationController 

    before_action :set_user!, only: [:index] # ... 
    before_action :set_note!, only: [:show, :edit, :update, :destroy] 

    def index 
    @notes = policy_scope(Note.all) 
    authorize(@user) 
    end 

    # ... 

    private 
    def set_user! 
     @user = User.find(params[:user_id]) 
    end 

    def set_note! 
     @note = authorize(Note.find(params[:id])) 
    end 
end 

以這種方式使用before_action是一個不錯的模式,因爲它建立了授權所有的「成員」的行爲。

+0

感謝您的回覆,我很欣賞這個例子。我正在努力解決的主要問題是如何讓管理員在訪問不同的索引頁時能夠查看其他用戶的註釋(除了他們自己的註釋外)。如果可能的話,我寧可不要污染控制器,但似乎沒有簡單的方法將權限傳給一個額外的params變量來檢查。我明白了,這是有目的的,但是到目前爲止,實現它可能是一種更清晰的方式。我可能只是想念一些東西。 – Dom