Let’s say your users are trying to access some pdf files that you’re serving inline with wicked_pdf or any other gem of you choice that is a wrapper for wkhtmltopdf. But they have to sign in first.

What happens when you use devise and you hit pdf url as unauthorized user? By default your app will respond with 401 Unauthorized which will get converted into invalid pdf file and this kinda not what you want. Probably ;). This can be fairly easy resolved with the help of custom failure_app. Let the code speak for itself:

# config/initializers/devise.rb

# you should probably put this somewhere in lib/ ;-)
class MyFailureApp < Devise::FailureApp
def respond
# let's say we want to handle that pdf request nicely
if request.format == :pdf
pdf_redirect
else
super
end
end

protected

# Assuming you have new_user_session_path in your routes
# Devise is doing much much more magic, see scope_url
# for more insight!
def pdf_redirect
# after signing-in we want to redirect user back to requested pdf file
session["#{scope}_return_to"] = attempted_path if request.get?

# nothing fancy here, i18n_message & scope are provided by parent class
redirect_to :"new_#{scope}_session", format: :html, alert: i18n_message
end
end

Devise.setup do |config|
# ...
config.warden do |manager|
manager.failure_app = MyFailureApp
end
end

And that’s the simple remedy for our pain ;-).

You can also try playing with Devise.navigational_formats, unfortunately I regret that I didn’t wrote that blog-post few weeks ago, because I recall that I stumbled upon some issue while trying to solve it that way. I ended up with custom failure app after all, but right now I simply don’t remember exact reasoning :P.