[英]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.