我有一个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
答案 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