假设我有一个带有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也做了类似的事情,如果一个用户没有被授权做某事,它就会引发你自己应该捕获的异常。
答案 0 :(得分:0)
错误有效,您渲染的时间超过一次,这就是doublerender
异常的原因。最好只在控制器中保持渲染
试试此代码
def show
is_client_valid = authenticate_license if params[:format] == 'json'
# boilerplate
respond_to do |format|
format.html
if is_client_valid == 'valid' #you can have a switch statement here, so that you can easily set the status tag
format.json { render json: @article, status: :ok }
else
format.json { render json: is_client_valid }
end
end
end
# in application_controller
def authenticate_license
@client = params[:client]
licenses = License.where(:code => params[:code])
@license = licenses.first
if @license
if @license.client = @client
return 'valid'
else
return 'wrong client'
end
else
return 'bad licence'
end
end