Pundit:授权命名空间控制器内的操作
Pundit: authorize actions within namespaced controllers
我有一个具有不同状态的 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
当你没有命名空间时,你就是这样做的。
尝试让命名空间与 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
不知道如何路由到命名空间策略并传入 Blog
记录。但是:以下是当您的命名空间策略只能根据当前用户的 permissions/roles:
进行授权时的操作方法
#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
我有一个具有不同状态的 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
当你没有命名空间时,你就是这样做的。
尝试让命名空间与 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
不知道如何路由到命名空间策略并传入 Blog
记录。但是:以下是当您的命名空间策略只能根据当前用户的 permissions/roles:
#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