I want to respond to CanCan::AccessDenied
with JSON if the request is via AJAX, but it is always responding with status 200 and a redirect regardless. I want to implement this answer: https://stackoverflow.com/a/10013873/148844. I don't know how it is overriding the status 302 to 200, let alone not rendering JSON. I also tried format.js
but that didn't work.
application_controller.rb
class ApplicationController < ActionController::Base
include CanCan::ControllerAdditions
rescue_from CanCan::AccessDenied do |exception|
flash[:warning] = exception.message
logger.info exception
respond_to do |format|
logger.info "format: " + format.to_s
format.html do
if user_signed_in? && current_user.type
redirect_to "/dashboard"
else
redirect_to root_path
end
end
format.json do
render json: {success: false, message: 'Access Denied: '+exception.message}, status: 401
end
end
end
CoffeeScript
$.post "/topics/order", {'id_order[]': arr}, (data, textStatus, jqXHR) ->
...
Gemfile
gem 'cancancan', '~> 1.10'
Console
Started POST "/topics/order" for ::1 at 2018-09-14 14:44:33 -0400
...
You are not authorized to access this page.
format: #<ActionController::MimeResponds::Collector:0x0000000d4b2a28>
Redirected to http://localhost:3000/dashboard
Completed 200 OK in 314ms (ActiveRecord: 28.0ms)
https://github.com/CanCanCommunity/cancancan#4-handle-unauthorized-access
https://api.rubyonrails.org/classes/ActionController/MimeResponds.html#method-i-respond_to
I've done some testing and added
format.json { head :forbidden, content_type: 'text/html' }
format.js { head :forbidden, content_type: 'text/html' }
To the top of respond_to
block and it does work. When moved to the bottom of the block, it doesn't work. Rails seems to be responding to the very first format
it sees, regardless of the format!