代码之家  ›  专栏  ›  技术社区  ›  LizGee

Ruby Pundit授权用户和合作者

  •  1
  • LizGee  · 技术社区  · 9 年前

    这里是Ruby初学者。我目前正在做一个项目,用户可以创建公共和私人Wiki。有三种不同的角色:管理员、标准用户和高级用户。标准用户只能查看公共Wiki。

    授权通过以下方式正常工作 行家 ,我已经成功地列出了我希望每个用户都能访问的Wiki,但我缺少了一件事:标准用户作为合作者添加到的Wiki。

    协作者不是角色,所以我很难将这些Wiki添加到索引中( Wiki通过合作者拥有许多用户 ).

    如果你对我如何实现这一点有什么想法,或者可能是一条替代路线,我很乐意听到他们的意见。

    目前,标准用户只能访问公共Wiki和他或她创建的Wiki(默认情况下是公共的)。目前,标准用户 可以 查看和编辑他或她添加到的私人wiki,但只能通过访问直接的wiki url。

    这是我的代码目前的样子:

    维基.rb

    class Wiki < ActiveRecord::Base
      belongs_to :user
      has_many :collaborators
      has_many :users, through: :collaborators
    
      scope :visible_to, -> (user) { user && (user.premium? || user.admin?) ? all : where(public: true)  }
      scope :publicly_visible, -> {where(public: true)}
    end
    

    wiki_策略.rb

    class WikiPolicy < ApplicationPolicy
      def index?
        true
      end
    
      def show?
        record.public? || user.present? && (record.user == user || user.admin? || user.premium? || record.users.include?(user))
      end
    
      def create?
        user.present? 
      end
    
      def new?
        create?
      end
    
      def update?
        user.present? && (record.user == user || user.admin? || record.users.include?(user))
      end
    
      def destroy?
        update?
      end
    
      class Scope
        attr_reader :user, :scope
    
        def initialize(user, scope)
          @user = user
          @scope = scope
        end
    
        def resolve
          if @user.present?
            wikis = Wiki.visible_to(@user)
          else
            wikis = Wiki.publicly_visible
          end
        end
      end
    end
    

    wikis_controller.rb

    class WikisController < ApplicationController
      def index
        @wikis = policy_scope(Wiki).paginate(page: params[:page], per_page: 10)
        authorize @wikis 
      end
    ...
    end
    
    2 回复  |  直到 9 年前
        1
  •  0
  •   Michael Do    9 年前

    你好,同学们!

    尝试将此添加到策略范围:

    def resolve
      if @user.present?
        wikis = Wiki.visible_to(@user)
        Wiki.all.each do |wiki|
            if wiki.users.include?(@user)
                wikis << wiki
            end
        end
        wikis
      else
        wikis = Wiki.publicly_visible
      end
    end
    

    此外,我注意到,您的高级用户可以查看所有私人Wiki,而不仅仅是他们自己的。

    编码愉快!

        2
  •  0
  •   LizGee    9 年前

    谢谢迈克尔!

    最初,我遇到了一个问题,在尝试通过作用域构建wiki数组后,will_page无法工作。这就是为什么我们走了一条不同的路线,在Wiki模型中使用了visible_to等作用域。

    然而,在试图解决这个问题时,我找到了一种方法,使我们的数组保持检查点所希望的方式,并对它们进行分页。

    我的政策现在是这样的:

    class WikiPolicy < ApplicationPolicy
      def index?
        true
      end
    
      def show?
        record.public? || user.present? && (record.user == user || user.admin? || user.premium? || record.users.include?(user))
      end
    
      def create?
        user.present? 
      end
    
      def new?
        create?
      end
    
      def update?
        user.present? && (record.user == user || user.admin? || record.users.include?(user))
      end
    
      def destroy?
        update?
      end
    
      class Scope
       attr_reader :user, :scope
    
       def initialize(user, scope)
         @user = user
         @scope = scope
       end
    
       def resolve
         wikis = []
         if user.present?
          if user.admin?
           wikis = scope.all 
         elsif user.premium?
           all_wikis = scope.all
           all_wikis.each do |wiki|
             if wiki.public? || wiki.user == user || wiki.users.include?(user)
               wikis << wiki
             end
           end
         else 
           all_wikis = scope.all
           wikis = []
           all_wikis.each do |wiki|
             if wiki.public? || wiki.users.include?(user)
               wikis << wiki 
             end
           end
         end
        end
         wikis
       end
     end
    end
    

    维基.rb

    class Wiki < ActiveRecord::Base
      belongs_to :user
      has_many :collaborators
      has_many :users, through: :collaborators
    end
    

    通过在config/ininitializers中添加以下文件,我能够分页并显示正确的wiki列表(包括collab wiki)

    数组分页.rb

    需要“will_page/array”