Pundit:授权命名空间控制器中的操作

时间:2016-04-18 17:25:19

标签: ruby-on-rails ruby pundit

我有一个Blog模型,它有不同的状态。为了保持一个瘦的控制器并遵循每个控制器只有CRUD操作的约定,我跟着DHH's namespacing controllers pattern并命名为Blog控制器。

现在我有一个Blogs::NewDraft控制器,一个Blogs::AwaitingApproval控制器和一个Blogs::Active控制器。

问题在于编写我的策略以授权这些命名空间控制器中的操作。所有命名空间控制器中的所有操作都授权相同的Blog模型对象。问题是我需要每个命名空间控制器在匹配的命名空间策略中进行授权(而不是在同一blog_policy.rb文件中授权的所有命名空间控制器。)

基本示例:对于具有非命名空间的restful控制器的restful资源,您可以这样做:

#app/controllers/blogs_controller.rb
class BlogsController < ApplicationController
  def index
    authorize :blog
    @blogs = Blog.all
  end

  def show
    @blog = Blog.find(1)
    authorize @blog
  end
end

现在匹配的政策

#app/policies/blogs_policy.rb
class BlogPolicy < ApplicationPolicy
  def index?
    user.admin?
  end

  def show?
    record.author == current_user
  end
end

当你没有命名空间时,你会这样做。

尝试让Namespacing与Pundit合作的当前代码:我是命名空间。我仍在授权Blog对象,但我需要在命名空间策略中授权每个命名空间控制器中的操作:

#app/controllers/blogs/new_drafts.rb
class Blogs::NewDraftsController < ApplicationController
  def index
    # doesn't work
    authorize Blog::NewDrafts
    @blogs = Blog.new_drafts
  end
  def show
    @blog = Blog.find(1)
    #doesn't work either
    authorize @blog, Blog::NewDraft
  end
end

所以我希望该命名空间控制器不路由到app/policies/blog_policy.rb,而是路由到app/policies/blogs/new_draft_policy.rb

#app/policies/blogs/new_draft_policy.rb
class Blogs::NewDraftPolicy < ApplicationPolicy
  def index?
    user.admin?
  end

  def show?
    # the record is a blog from the Blog Model
    record.author == current_user
  end
end

Pundit Documentation and Usage

1 个答案:

答案 0 :(得分:1)

不知道如何路由到命名空间策略并传入Blog记录。但是:当您的命名空间策略只能根据当前用户的权限/角色进行授权时,以下是您的操作方法:

#app/controllers/blogs/new_drafts.rb
class Blogs::NewDraftsController < ApplicationController
  def index
    authorize [:blogs, :new_draft]
    @blogs = Blog.new_drafts
  end
end

#app/policies/blogs/new_draft_policy.rb
class Blogs::NewDraftPolicy < ApplicationPolicy
  def index?
    user.admin?
  end
end