管理员和用户的权威指数方法

时间:2014-12-11 02:58:32

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

所以,我试图使用宝石评论员。我只想弄清楚如何为用户和管理员提供索引视图。我想为管理员呈现所有结果,仅为用户呈现相关帖子。我在github上搜索并搜索过,但我没有找到任何运气。我必须在政策和控制器中加入什么?

原始代码

class PostsPolicy
   attr_reader :current_user, :model

  def initialize(current_user, model)
    @current_user = current_user
    @post = model
  end

  def index?
    @current_user.admin?
  end
end

控制器

class PostsController < ApplicationController
  before_filter :load_user
  before_filter :authenticate_user!
  after_action :verify_authorized

  def index
    @posts = Post.order('title').page(params[:page]).per(25)
    authorize User
  end

private

  def load_user
    @user = User.find_by_id(params[:user_id])
  end

end

第二次更新

class PostsPolicy
 class Scope
  attr_reader :user, :scope

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

  def resolve
    if user.admin?
      scope.all
    else
      scope.where(user: user)
    end
   end

  end

end

控制器

class PostsController < ApplicationController
  before_filter :load_user
  before_filter :authenticate_user!
  after_action :verify_authorized

 def index
   @posts = policy_scope(Post).order('title').page(params[:page]).per(25)
   authorize User
 end

private

 def load_user
   @user = User.find_by_id(params[:user_id])
 end
end

第三次更新

class PostPolicy

   class Scope
    attr_reader :user, :scope

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

      def resolve
        if user.admin?
          scope.all
        else
          scope.where(user: user)
        end
      end
   end

  def index?
   user.admin? || user.posts.count > 0
  end
end

控制器

class PostsController < ApplicationController
  before_filter :load_user
  before_filter :authenticate_user!
  after_action :verify_authorized

 def index
   @posts = policy_scope(Post).order('title').page(params[:page]).per(25)
   authorize User
 end

private

 def load_user
   @user = User.find_by_id(params[:user_id])
 end

end

** 使用工作代码进行最终更新 **

class PostPolicy
attr_reader :user, :model

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

   class Scope
    attr_reader :user, :scope

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

      def resolve
        if user.admin?
          scope.all
        else
          scope.where(user: user)
        end
      end
   end

  def index?
   user.admin? || user.posts.count
  end
end

控制器

class PostsController < ApplicationController
  before_filter :load_user
  before_filter :authenticate_user!
  after_action :verify_authorized

 def index
   @posts = policy_scope(Post).order('title').page(params[:page]).per(25)
   authorize Post
 end

private

 def load_user
   @user = User.find_by_id(params[:user_id])
 end

end

1 个答案:

答案 0 :(得分:7)

您正在寻找的是范围:

class PostsPolicy
  class Scope
    attr_reader :user, :scope

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

    def resolve
      if user.admin?
        scope.all
      else
        scope.where(user: user)
      end
    end
  end
end

然后在您的控制器中

def index
  @posts = policy_scope(Post).order('title').page(params[:page]).per(25)
  authorize User
end

修改

作为旁注,authorize User从长远来看可能不会很好。您实际上是在创建一个需要为每个索引提供服务的索引策略。如果您想授权索引页面的可见性,您仍然可以在策略中执行以下操作:

def index?
  user.admin? || user.posts.count > 0
end

假设已建立关系,那么您可以在policy_scope之前调用索引控制器中的authorize Post