【发布时间】:2017-01-15 21:01:47
【问题描述】:
在过去 2 年多的时间里,我一直在努力学习如何使用 pundit。
我正在尝试编写范围策略,以便不同的用户可以根据他们适合的范围类接收对象。
我之前就同一主题提出了几个问题,但我离解决方案还差得远。我最近的问题是:here, here、here、here、here 和 here。
还有其他几个,但这些给出了总体情况,我正在努力了解如何开始的基础知识。
我在开始时遇到了一百万个问题,并意识到经过 4 年的尝试(每天 - 10 多个小时),我在学习编码方面并没有真正走多远,但我目前面临的问题是出现此错误:
wrong number of arguments (given 2, expected 0)
它指向我将 authorize @eoi 行放在控制器中的任何位置。我之前问过这个错误here
我原来是在set_eoi方法中放入如下:
def set_eoi
@eoi = Eoi.find(params[:id])
authorize @eoi
end
我在控制器的 before 操作中使用了该方法:
before_action :set_eoi, only: [:show, :edit, :update, :destroy]
当我找到this 帖子的答案时,我停止了这样做,该帖子说不要在之前的操作中使用授权(即使权威人士的 Go Rails 视频教程显示这样做)。
然后,我将授权调用移至显示操作本身:
def show
authorize @eoi
end
这会产生与在之前的操作中使用它相同的错误。
请,有人可以帮助开始。我目前的设置如下:
目标
用户有个人资料。这些配置文件拥有他们创建的项目。其他用户可以表示有兴趣加入其他用户拥有的项目。创建项目的用户应该能够看到在他们自己的项目中提交的所有 eois。提交项目 eoi 的用户在查看项目页面时应该只看到他们自己的 eoi。此外,每个用户都可以看到他们自己的 eois 的索引(无论他们在哪个项目上提交了 eois)。
我目前采用的方法是为同一个控制器制定两个策略(尽管我认为this 问题可能解决了这不是一个好的方法)。
我有用户、个人资料的模型。项目和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
当我保存所有这些并尝试它时,我可以正确呈现所有索引(尽管当我将 authorize @eois 添加到 eois 控制器中的索引操作时我不能。
我无法渲染显示页面。相反,我收到一条错误消息:
ArgumentError at /projects/26/eois/24
wrong number of arguments (given 2, expected 0)
我不知道这个错误信息是什么意思。我只在 eoi 控制器的 show 动作中为 authorize 方法提供了一个参数 - 所以我觉得这个错误认为我给出了 2 对我来说很奇怪。
我已经看到 this 帖子,其中用户似乎有与我相同的错误消息,尽管该帖子中的答案突出显示了该用户设置中的一些我自己没有的错误。
谁能看出我哪里出错了?在我看来,该索引之所以有效,是因为我没有尝试向它添加 authorize @eois。范围对于索引目的是正确的。当我尝试授权时,显示操作根本不起作用。
【问题讨论】:
标签: ruby-on-rails ruby scope parameter-passing pundit