respond_to do |format|...end, already running in this app's 404 handler
One matched route, more than one shape of answer
Nested resource routing, the course before this one, traced how a request reaches a controller action. That's half the job. Once an action like Admin::Catalog::Lessons::ImagesController#destroy runs, it has to decide what to send back, and in this app there's often more than one right answer: a full HTML page or redirect for a browser navigating directly, a small Turbo Stream fragment for an in-place update, sometimes a bare status code. respond_to do |format| ... end is how one action offers several of those and picks the one the current request needs.
This app's example: ApplicationController#render_not_found
rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
def render_not_found
respond_to do |format|
format.html do
@not_found = not_found_context
@suggested_courses = Public::NotFoundSuggestionsQuery.call.courses
render "errors/not_found", status: :not_found
end
format.any { head :not_found }
end
end
Every ActiveRecord::RecordNotFound raised in this app, from a bad course slug to a missing lesson, ends up here. format.html, given a block, builds a themed 404 page: @not_found, @suggested_courses and a full render call. format.any, right below it, catches every other format in one line, head :not_found, with no body, no template and no view lookup.
What respond_to does with those two blocks
respond_to looks at the request, decides which format it wants (the next lesson covers how), and runs only the matching block. Rails' installed source, action_controller/metal/mime_responds.rb, shows the rule. A request resolving to :html runs format.html's block and nothing else; a request resolving to anything else, :json, :turbo_stream or another format, runs format.any's block. It never runs both. If the resolved format matches no block and there's no format.any to catch it, Rails raises ActionController::UnknownFormat.
What this course covers
Seven lessons, with every controller quoted from this app's source. Lesson 2 covers how a request's format is decided, read from Rails' installed mime_negotiation.rb. Lesson 3 covers the no-block shorthand that this app's covers_controller.rb uses next to the explicit block form. Lesson 4 covers format.any and its alias format.all, as Rails' source defines them. Lesson 5 covers an action, comments_controller.rb#create, that branches on success and failure differently inside each format block. Lesson 6 covers this app's route that forces a format before any negotiation happens. Lesson 7 shows how three patterns for handling format, all live in this app, add up to one decision.
Keep going with lesson 2
How the format is chosen, in Rails' installed source
The order Rails uses to pick a format: format parameter, Accept header, path extension, XHR, then HTML.
A free account also gives you the quizzes, your progress and notes, and the discussion.