假设我有一个带有 show 方法的articles_controller
我想确保只有具有有效许可证代码的客户端才能读取此控制器操作的 json 端点
def show
authenticate_license if params[:format] == 'json'
# boilerplate
respond_to do |format|
format.html
format.json { render json: @article, status: :ok }
end
end
我可能想在其他地方使用这个身份验证块,所以我把它放到我的 application_controller
# in application_controller
def authenticate_license
@client = params[:client]
licenses = License.where(:code => params[:code])
@license = licenses.first
if @license
if @license.client = @client
# do nothing, we're fine
else
respond_to do |format|
format.json { render json: 'wrong client', status: 400 }
end
end
else
respond_to do |format|
format.json { render json: 'bad license', status: :forbidden }
end
end
end
但这会导致双重渲染错误,所以现在我将尝试不同的东西
# in application_controller
def authenticate_license
licenses = License.where(:code => params[:code]
@license = licenses.first
if @license
if @license.client = @client
# do nothing, we're fine
else
raise ActionController::RoutingError.new('wrong client')
end
else
raise ActionController::RoutingError.new('bad license code')
end
end
rescue_from ActionController::RoutingError do |exception|
respond_to do |format|
format.html { redirect_to root_url, :alert => exception.message }
format.json { render json: exception.message, status: :forbidden }
end
end
但这样一来,我就无法指定 HTTP 状态,而且我还捕获了我可能不想捕获的路由错误。
做我想做的事情的正确方法是什么?
我所描述的行为就是设计所做的。如果您向具有 authorize_user 的操作发出请求!例如,它会引发错误,并将用户重定向到某个页面。CanCan 也做了类似的事情,如果用户没有被授权做某事,它会引发你应该捕获的自己的异常。