Pundit:在嵌套资源中使用auhorize Index

时间:2015-10-23 13:36:10

标签: ruby-on-rails-4 nested authorization pundit

使用Rails 4.2.4与Devise(3.5.2)和Pundit(1.0.1)。 Decent_exposure(2.3.2)。

我为User和Idea设置了一个简单的嵌套关联:

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

然后我只是试图禁止访问users / 1 / ideas如果current_user不是Ideas的所有者(在本例中,如果current_user.id!= 1)。 我无法弄清楚该怎么做。我能够在索引视图中只显示current_user Ideas:

[创意控制器]

def show
  authorize idea
end

[思想政策]

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

但是如何阻止用户只是导航到其他用户的Idea索引页面? 我想在Ideas控制器中我应该使用类似的东西:

def index
  authorize user
end

但那又怎么样?如何向用户政策发送有关Idea集合的信息? 或者我应该通过创意政策本身进行授权吗?

1 个答案:

答案 0 :(得分:8)

此处复制my response on GitHub,因为这会获得更多流量。

一种方法是创建用户拥有的存根Idea以进行授权。

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

  authorize idea

  # ...
end

以及index?

中的IdeaPolicy方法
def index?
  record.user_id = user.id
end

另一种方法是更改​​您要授权的内容。而不是针对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