Jay*_*ong 0 ruby ruby-on-rails
我有我的rails应用程序并试图通过添加一个名为cancancan的gem制作的方法来添加权限.所以下面有两种方法.
def find_review
@review = Review.find(params[:id])
end
def authorize_user!
unless can? :manage, @review
redirect_to product_path(@review.product)
end
end
Run Code Online (Sandbox Code Playgroud)
有两种情况.案例1:调用destroy内部的方法动作
def destroy
find_review
authorize!
@product = @review.product
@reviews = @product.reviews
@review.destroy
end
Run Code Online (Sandbox Code Playgroud)
和案例2:使用before_action方法调用方法
before_action :find_review, :authorize!, only: [:destroy]
def destroy
@product = @review.product
@reviews = @product.reviews
@review.destroy
redirect_to product_path(@product), notice: 'Review is deleted'
end
Run Code Online (Sandbox Code Playgroud)
我使用before_action(案例2)甚至在调用操作之前重定向未经授权的用户,这样才有意义.我想知道的是在案例1中,为什么授权方法在销毁审核之前不会中断和重定向用户?它实际上重定向,但删除审查后.但我认为红宝石是同步的..
正如其他人已经注意到的那样,你authorize!不会中断请求,只会添加一个标题,然后继续进行破坏等等.从嵌套方法调用中断流的一种很好的可靠方法是引发异常.像这样的东西:
class ApplicationController
NotAuthorizedError = Class.new(StandardError)
rescue_from NotAuthorizedError do
redirect_to root_path
end
end
class ReviewsController < ApplicationController
def authorize!
unless can?(:manage, @review)
fail NotAuthorizedError
end
end
def destroy
find_review
authorize! # if user is not authorized, the code below won't run
# because of the exception
@product = @review.product
@reviews = @product.reviews
@review.destroy
end
end
Run Code Online (Sandbox Code Playgroud)
您可以通过集成cancan来解决问题,因为它确实包含异常提升authorize!.你应该能够做到这一点:
def destroy
find_review
authorize! :manage, @review # can raise CanCan::AccessDenied
@product = @review.product
@reviews = @product.reviews
@review.destroy
end
Run Code Online (Sandbox Code Playgroud)
或更好
load_and_authorize_resource
def destroy
@product = @review.product
@reviews = @product.reviews
@review.destroy
end
Run Code Online (Sandbox Code Playgroud)