7

所以,我正在尝试使用宝石专家。我只是想弄清楚如何为用户和管理员提供索引视图。我想为管理员呈现所有结果,只为用户呈现相关帖子。我已经在 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
4

1 回答 1

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

假设建立了关系,那么您将authorize Post在您的 policy_scope 之前调用您的索引控制器。

于 2014-12-11T03:12:33.523 回答