2015-10-23 41 views
2

使用Rails 4.2.4和Devise(3.5.2)和Pundit(1.0.1)。 Decent_exposure(2.3.2)。Pundit:auhorize嵌套资源中的索引

我有用户和想法简单的嵌套associaton:

class User < ActiveRecord::Base 
has_many :ideas 
... 

class Idea < ActiveRecord::Base 
belongs_to :user 
... 

在routes.rb中

devise_for :users 

resources :users do 
    resources :ideas 
end 

话,我只是想,如果CURRENT_USER是不允许用户访问/ 1 /想法而不是想法的所有者(在本例中,如果current_user.id!= 1)。 我想不出如何去做。我能够只显示在索引视图中的CURRENT_USER理念与:

[创意控制]

def show 
    authorize idea 
end 

[思想政策]

def show? 
    @current_user == @idea.user 
end 

但我怎么能阻止用户简单地导航到其他用户的创意索引页面? 我想,在思想控制我应该使用类似:

def index 
    authorize user 
end 

但是然后呢?如何向用户政策发送有关Idea集合的信息? 或者我应该通过创意政策本身进行授权吗?

回答

6

在这里复制my response on GitHub因为这会获得更多流量。


一种方法是创建一个存根Idea用户拥有授权反对。

def index 
    @user = User::find(params[:user_id]) 
    idea = Idea.new(user_id: @user.id) 

    authorize idea 

    # ... 
end 
IdeaPolicy

def index? 
    record.user_id = user.id 
end 

另一种方式

index?方法是改变你授权反对什么。而不是针对Idea进行授权,而是针对User进行授权。

def index 
    @user = User::find(params[:user_id]) 

    authorize @user, :show_ideas? 

    # ... 
end 

,并创建一个新的show_ideas?方法您UserPolicy

def show_ideas? 
    user.id == record.id 
end 
+0

它完美!非常感谢。第二种方法对我来说更直观。再次感谢! – Galen

+0

第二种方法更明确,更易于理解。 :) –

+0

deefour,哪一个是首选的方式? (我正在使用设计进行身份验证) –