簡體   English   中英

Rails 4 - Pundit,Scopes:入門

[英]Rails 4 - Pundit, Scopes: Getting Started

在過去2年多的努力中,我真的在努力學習如何使用專家。

我正在嘗試編寫范圍策略,以便不同的用戶可以根據他們適合的范圍類接收對象。

我之前曾就同一主題提出了幾個問題,但我沒有接近解決方案。 我最近的問題是: 這里這里這里這里這里這里

還有其他幾個,但這些給出了總體情況,我正在努力解決如何開始的基本原理。

我有一百萬個入門問題,並意識到經過4年的嘗試(每天 - 10多個小時),我在嘗試學習編碼方面並沒有真正走得太遠,但我面臨的當前問題是這個錯誤:

wrong number of arguments (given 2, expected 0)

它指向我在我的控制器中放置授權@eoi線的任何地方。 我之前在這里詢問過這個錯誤

我最初放入set_eoi方法如下:

 def set_eoi
      @eoi = Eoi.find(params[:id])
      authorize @eoi
    end

我在控制器中的before操作中使用該方法:

before_action :set_eoi, only: [:show, :edit, :update, :destroy]

當我找到這篇文章的答案時,我就停止這樣做了, 帖子說在之前的行動中不使用授權(即使權威的Go Rails視頻教程顯示這樣做)。

然后,我將授權調用移動到show動作本身:

  def show
    authorize @eoi
  end

這會產生與在before操作中使用它相同的錯誤。

請有人幫助您入門。 我目前的設置如下:

目的

用戶有個人資料。 這些簡檔擁有他們創建的項目。 其他用戶可以表達對加入另一個用戶擁有的項目的興趣。 創建項目的用戶應該能夠看到他們自己項目中提交的所有eois。 在項目頁面上查看項目頁面時,在項目上提交eoi的用戶應該只能看到自己的eoi。 此外,每個用戶都可以看到他們自己的eois的索引(無論他們提交eoi的項目是什么)。

我目前采取的方法是為同一個控制器制定兩個策略(盡管我認為這個問題可能解決了這個問題並不是一個好的方法)。

我有User,Profile的模型。 項目和Eoi。 協會是:

class User < ActiveRecord::Base
  has_one :profile
  has_many :eois
end

class Profile < ActiveRecord::Base
  belongs_to :user
  has_many :projects, dependent: :destroy
end

class Project < ActiveRecord::Base
  belongs_to :profile
  has_many :eois
end

class Eoi < ActiveRecord::Base
  belongs_to :project
  belongs_to :user
end

我的路線文件有:

resources :eois#, only: [:index]
  concern :eoiable do
    resources :eois
  end

resources :projects do
    member do
  concerns :eoiable
end

我有Eoi政策和項目Eoi政策,如下:

class EoiPolicy < ApplicationPolicy

  class Scope

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

    def resolve
      # selects all the EOI's for a given user
      @scope.where(user_id: @user.id)
    end

  end

  def index?
    true
  end

  def new?
    true
  end

  def show?
#     record.user_id == user.id || user.profile.project_id == record.project_id
    true
  end

  def edit?
    user.id == eoi.user.id?
  end

  def create?
    true
  end

  def update?
    user.id == eoi.user.id?
  end

  def destroy?
    user.id == eoi.user.id?
  end


end


class ProjectEoiPolicy < ApplicationPolicy
  class Scope < Scope
    def resolve(project_id)
      project = Project.find(project_id)
      if project.owner?(@user)
        # if the user is the owner of the project, then get
        # all the eois
        project.eois
      else
        # select all the eois for the project
        # created by this user
        Eoi.for_user(@user.id).for_project(project_id)
      end
    end
  end

end

我的eois控制器有:

class EoisController < ApplicationController
  before_action :get_project, except: [:index, :show]
  before_action :set_eoi, only: [:show, :edit, :update, :destroy]
  # before_action :load_parent
  # before_action :load_eoi, only: [:show, :edit, :update, :destroy]


  def index
    if params[:project_id]
      @eois = ProjectEoiPolicy::Scope.new(current_user, Eoi).resolve(params[:project_id])
    else
      @eois = policy_scope(Eoi)
    end
  end


  # GET /eois/1
  # GET /eois/1.json
  def show
    authorize @eoi
  end

我的申請政策有:

class ApplicationPolicy
  attr_reader :user,  :scope

  class Scope
    def initialize(user, scope)
      #byebug        
      @user = user
      # record = record
      @scope = scope
    end

    def resolve
      scope
    end
  end

  def index?
    false
  end

  def show?
    scope.where(:id => record.id).exists?
  end

  def create?
    false
  end

  def new?
    create?
  end

  def update?
    false
  end

  def edit?
    update?
  end

  def destroy?
    false
  end

  def scope
    Pundit.policy_scope!(user, record.class)
  end

當我保存所有這些並嘗試它時,我可以正確地渲染所有索引(雖然我在將這樣的@eois添加到eois控制器中的索引操作時不能這樣做。

我無法獲得要顯示的節目頁面。 相反,我得到一個錯誤,說:

ArgumentError at /projects/26/eois/24
wrong number of arguments (given 2, expected 0)

我不知道這個錯誤信息的含義。 我只是在eoi控制器的show動作中為authorize方法提供了一個參數 - 所以我很奇怪這個錯誤認為我給了2。

我已經看過這篇帖子,用戶似乎和我有相同的錯誤信息,盡管該帖子中的答案突出顯示了該用戶設置中我自己沒有的一些錯誤。

誰能看到我哪里出錯了? 在我看來,索引只能起作用,因為我沒有嘗試將authorize @eois添加到它。 范圍適用於索引目的。 當我嘗試授權時,show動作根本不起作用。

好的,關於Pundit文檔: https//github.com/elabs/pundit

該示例似乎表明Policy Scope需要從applicationPolicy的范圍繼承:

class PostPolicy < ApplicationPolicy
  class Scope < Scope

所以我猜你應該試試這個:

class EoiPolicy < ApplicationPolicy
  class Scope < Scope # this is the changed line of code

同樣,您擁有的應用程序策略在范圍之外有attr_readers,其中權威示例將它們放在其中,例如:

class ApplicationPolicy
  # should not be here
  # attr_reader :user,  :scope

  class Scope
    # should be here instead
    attr_reader :user,  :scope

這可能會讓你超越這個問題,當你需要讀者時,你會深入潛入@ -var:

def resolve
  # selects all the EOI's for a given user
  # should not use `@scope`
  # @scope.where(user_id: @user.id)
  # instead use `scope` which is the reader
  scope.where(user_id: @user.id)
end

無論這是否修復了你的bug ......你可能需要做這些事情:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM