Ruby Pundit授权用户和协作者

时间:2015-08-13 17:29:33

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

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

授权通过 Pundit 正常运行,我已成功列出了我希望每个用户都可以访问的wiki,但我遗漏了一件事:Wiki to to已将标准用户添加为协作者。

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

如果您对我如何实现这一点或任何其他途径有任何想法,我很乐意听到它们。

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

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

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

2 个答案:

答案 0 :(得分:0)

大家好兄弟你好!

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

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,而不仅仅是他们自己的。

快乐的编码!

答案 1 :(得分:0)

谢谢迈克尔!

最初,我遇到了一个问题,在尝试通过示波器构建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

要求&#39; will_paginate / array&#39;