Rails 4 - 与Rolify合作 - 允许一组角色

Mel*_*Mel 6 permissions roles ruby-on-rails rolify pundit

我正在尝试用Rails 4创建一个应用程序.

我已经用Rolify gem定义了一系列角色.

现在,我想使用权威来允许有角色的用户做某些事情.在不止一种角色可以做某件事的情况下,我已经定义了一组角色.

在我的application_policy中,我定义了私有方法,这些方法列出了我想在权威权限中使用的角色组.

我的应用程序策略实例化用户和记录.然后我将记录定义为相关模型的名称(与该模型的策略名称相同).

我有:

class ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end

  def index?
    false
  end

  def show?
    scope.where(:id => record.id).exists?
  end

  def create?
    false
  end

  def new?
    create?
  end

  def update?
    false
  end

  def edit?
    update?
  end

  def destroy?
    false
  end

  def scope
    Pundit.policy_scope!(user, record.class)
  end

  class Scope
    attr_reader :user, :scope

    def initialize(user, scope)
      @user = user
      @scope = scope
    end

    def resolve
      scope
    end
  end

  private


    def cf_legal
      [ :Admin, :CF_Legal, :CF_Policy_Manager ]
    end

    def cf_content
      [ :Admin, :CF_Author, :CF_Editor ]
    end


end
Run Code Online (Sandbox Code Playgroud)

然后在我的内容政策中,我想说:

def record
   content
end

def create
    user.has_role? :cf_content
end
Run Code Online (Sandbox Code Playgroud)

当我保存并尝试它时,我看不到我应该看到的东西(作为具有角色作者的用户.

任何人都可以看到如何做到这一点?

Jos*_*den 2

tl;dr:在您的策略类上使用查询方法。

首先,模型应该有自己的 Policy 类(可选)扩展您的 ApplicationPolicy 类。假设您的模型名为Post. 然后你可以做类似的事情:

class PostPolicy < ApplicationPolicy

   attr_reader :user, :post

   def initialize(user,post)
     @user = user
     @post = post
   end

   def create?
     cf_content.all? { |role| user.has_role?(role) }
   end

   private

   def cf_content
    [ :Admin, :Author, :Editor ]
   end
end


class PostsController
  def create
    @post = Post.new(params[:post])
    authorize @post, :create?
    # @post.save and redirect, etc.
  end
end
Run Code Online (Sandbox Code Playgroud)

授权调用将调用create?查询方法并检查用户是否具有 cf_content 中的角色。

您甚至可能不需要添加第二个参数 ,create?正如专家文档所述:

Authorize 方法自动推断 Post 将有一个匹配的 PostPolicy 类,并实例化该类,并提交当前用户和给定的记录。然后它从操作名称推断它应该调用更新?在这个政策实例上。

或者在你的情况下,create?而不是update?.