【问题标题】:Ruby Pundit Authorization Users and CollaboratorsRuby Pundit 授权用户和合作者
【发布时间】:2015-11-06 19:26:35
【问题描述】:

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

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

协作者不是角色,因此我很难将这些 wiki 添加到索引中(Wiki 通过协作者有很多用户)。

如果您对我如何实现此功能或替代路线有任何想法,我很乐意听到。

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

这是我的代码到目前为止的样子:

wiki.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_policy.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

【问题讨论】:

    标签: ruby-on-rails ruby has-many-through user-roles pundit


    【解决方案1】:

    同学们你好!

    尝试将此添加到您的政策范围:

    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】:

      谢谢迈克尔!

      最初,我遇到了一个问题,即在尝试通过范围构建 wiki 数组后 will_paginate 无法正常工作。这就是为什么我们走不同的路线并在 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
      

      wiki.rb

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

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

      array_paginate.rb

      需要'will_paginate/array'

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-03
        • 1970-01-01
        • 2014-06-23
        相关资源
        最近更新 更多