在rails中,定义Pundit范围子类以根据用户类型显示不同的帖子集

时间:2015-02-27 16:53:40

标签: ruby-on-rails devise scope authorization pundit

您好,我是ruby on rails的新手,目前正在进行一项练习,我有3种类型的用户(管理员,主持人和成员)。我使用Pundit宝石和Devise Gem。 我被要求定义Pundit范围类,以根据用户的角色访问帖子。

管理员和版主可以查看所有帖子。签名用户只能查看他的帖子。客人无法查看帖子。

这是PostsController:

class PostsController < ApplicationController
          def index
            @posts = policy_scope(Post.all)
            authorize @posts
          end

          def show
            @post = Post.find(params[:id])
          end

          def new
            @post = Post.new
            authorize @post
          end

          def create 
            @post = current_user.posts.build(params.require(:post).permit(:title, :body))
            authorize @post
            if @post.save
              flash[:notice] = "Post was saved"
              redirect_to @post
            else
              flash[:error] = "There was an error saving the post. Please try again"
              render :new
            end
          end

          def edit
            @post = Post.find(params[:id])
            authorize @post
          end
          def update 
            @post = Post.find(params[:id])
            authorize @post
            if @post.update_attributes(params.require(:post).permit(:title, :body))
              flash[:notice] = "Post was updated."
              redirect_to @post
            else
              flash[:error] = "There was an error saving the post.Please try again."
              render :edit
            end
          end
        end

Here's my 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?
        user.present?
      end

      def new?
        create?
      end

      def update?
        user.present? && (record.user == user || user.admin?)
      end

      def edit?
        update?
      end

      def destroy?
        update?
      end

      def scope
        record.class
      end

      class Scope
        attr_reader :user, :scope

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

        def resolve
          scope
        end
      end
    end

我的邮政政策:

class PostPolicy < ApplicationPolicy 


  class Scope < Scope 
    def resolve 
      if user.admin? || user.moderator? 
      scope.all

      else
      scope.where(:id => user.id).exists?
      end
    end
  end 


  def index?
    user.admin? || user.id?
  end

end

此外,我是否可以在任何地方阅读或了解有关Pundit范围政策和轨道授权的更多信息?

2 个答案:

答案 0 :(得分:0)

如果您要使用Pundit政策,请务必始终编写方法以在用户模型中声明管理员和管理员

def admin?
  role == 'admin'
end

def moderator?
  role == 'moderator'
end

答案 1 :(得分:0)

有一种更好的方法来定义管理员,管理员和成员。先做:

rails g migration AddRoleToUsers role:integer

然后在您的用户模型中创建一个枚举

enum role: [:member, :moderator, :admin] # add whatever roles you want 

枚举会自动为每个角色创建一个

.member? # checks if role is member
.member! # turns the user into a member so like current_user.member!
 # and the same for all other roles.

不确定这是否真的有用,但希望你觉得它很有用!