Ruby on rails 为什么声明性_授权会破坏我的控制器的功能?-轨道3
我有一个带有两个动作的Ruby on rails 为什么声明性_授权会破坏我的控制器的功能?-轨道3,ruby-on-rails,ruby-on-rails-3,declarative-authorization,Ruby On Rails,Ruby On Rails 3,Declarative Authorization,我有一个带有两个动作的优惠券控制器 class CouponsController < ApplicationController filter_resource_access def index @coupons = Coupon.all end #generates 10 new coupons on each call def generate plan_id = params[:plan_id] numdays = params[:n
优惠券控制器
class CouponsController < ApplicationController
filter_resource_access
def index
@coupons = Coupon.all
end
#generates 10 new coupons on each call
def generate
plan_id = params[:plan_id]
numdays = params[:num_days]
(1..10).each do |i|
validChars = %w{ 1 2 3 4 5 6 7 9 a A b B d D e E f g G h H j J k K m M n N p P q Q r R t T }.to_a
code = (0...6).map{ validChars[ rand(validChars.size) ] }.join
coupon = Coupon.new
coupon.code = code
coupon.plan_id = plan_id
coupon.active = false
coupon.subdays = numdays
coupon.save
end
redirect_to :coupons_path
end
end
上述所有抛出的错误如下:
filter_access_to tried to find Coupon from params[:id] (nil), because attribute_check is enabled and @coupon isn't set, but failed: ActiveRecord::RecordNotFound: Couldn't find Coupon without an ID
Completed 404 Not Found in 245ms
ActiveRecord::RecordNotFound (Couldn't find Coupon without an ID):
但是,一旦我将filter\u resource\u access
更改为filter\u access\u改为:all,:except=>:generate
,它就不再给我错误,而且还可以正常工作
i、 e.它生成我正在寻找的一些优惠券代码,但它不包括视图输出中的计划id号或天数
为什么呢?我做错了什么
编辑1:顺便说一句,它确实限制了合适的人…即。只有指定的角色才能查看优惠券索引视图
。因此,过滤器部分工作 我的猜测是,filter\u resource\u access
将控制器中的所有操作视为处理单个资源,并尝试执行优惠券.find(params[:id])
。将其更改为:
filter_access_to :all, :except => :generate
您告诉它在该操作之前不要运行该方法,这意味着它不会尝试查找优惠券。声明性授权需要您将优惠券声明为实例变量
在控制器中,尝试将优惠券=优惠券.new
更改为@优惠券=优惠券.new
(显然要相应更改后续行)。filter\u resource\u access尝试为您创建资源对象,因此您需要查看:additional\u member
或:additional\u collection
选项,或者如您所述,使用除
选项
至于缺少的计划参数,您确定它们是作为params[:plan\u id]
输入的吗?检查您的devel日志,查看传入参数的样子
您也没有检查save
调用是否成功,因此如果有错误,您将无法知道。filter\u resource\u访问触发声明性auth框架,以对资源的:id参数执行查找(在非集合/创建者方法中)
在您的示例中,它将执行@优惠券=优惠券.find(params[:id]),并为控制器设置该成员变量。但是,由于没有参数[:id]通过该路由进入该操作,因此该操作失败
解决这个问题的方法是,在保持控制器权限的同时,非常简单。只需将其放在控制器顶部的filter_resource_访问线上:
filter_resource_access :additional_collection => { :generate => :read }
# I tried the two lines below but to no avail
#filter_resource_access :additional_collection => { :generate => :read }, :no_attribute_check => [ :generate ]
# filter_access_to :generate, :attribute_check => false
这将保持您对其他控制器操作以及“生成”操作的权限检查,但将“生成”方法从自动查找器查找中豁免
有关更多信息,请参阅:
问题在于,对于filter_resource_access,它假定控制器使用默认资源操作,并尝试为非标准crud的操作查找经销商if参数[:id]。
您需要做的是添加
filter_access_to :all
并将相应的规则:generate添加到authorization_rules.rb。
像
如果优惠券.started.nil?==正确
。只要如果优惠券.started.nil?
就可以了.K。固定的!剩下的呢?:)那么,如何让它“正常运行”,但仍然仅限于我在授权规则.rb
中指定的角色?read在这里做什么?我让它工作了,但有点不同。我使用了-filter\u resource\u access:collection=>[[:generate,:index],:index]
filter_resource_access :additional_collection => { :generate => :read }
# I tried the two lines below but to no avail
#filter_resource_access :additional_collection => { :generate => :read }, :no_attribute_check => [ :generate ]
# filter_access_to :generate, :attribute_check => false
filter_access_to :all
role :someone do
has_permission_on :coupon, :to => :generate
...
end