Turbo Teapot
You probably shouldn’t do this, but anyway… I’ve been upgrading an app from Turbolinks to Turbo, and there are a number of controller actions that render
successful responses after form submissions. Turbo expects the server to return an HTTP 303 See Other
response in these cases, so returning 2xx
won’t render anything. However, Turbo does render error responses (4xx
and 5xx
).
The HTTP status 418 I'm a teapot
was an April Fools’ joke, so it’s basically nonsense, but we can use it as a temporary workround for Turbo’s requirements. For example:
class PostsController < ApplicationController
def create
if @post = Post.create(post_params)
render status: (request.format.turbo_stream? ? 418 : :created)
else
render :new, status: :unprocessable_entity
end
end
end
My colleague Sam Oliver suggested wrapping this up in a patch, which ended up looking like this:
# lib/render_418_for_turbo.rb
module Render418ForTurbo
def render(*args)
message = "[Render418ForTurbo]: Responding with 418 status to work around Turbo's rendering limitation."
if !request.get? && request.format.turbo_stream?
if options = args.find { |arg| arg.is_a?(Hash) }
unless options[:status]
puts message # or my_logger.info message
options[:status] = 418
end
else
puts message # or my_logger.info message
args.push(status: 418)
end
end
super
end
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
prepend Render418ForTurbo
end
This patch adds a 418
statuses for non-GET
requests that were made via Turbo. It will only add the status if a status is not present, and will log the override.