Turboboost: Enhanced AJAX handling for Rails apps
This gem was renamed from
turboboost for a couple reasons:
- A simpler, unmaintained gem named
- The gem now provides enhanced AJAX handling to links and other non-form elements.
1 2 3
turboboost on Github for more.
In our app though, there are lots of forms that send POST and PUT requests. Every time a form gets submitted, the browser would wait for a response and then follow the success redirection or render the invalid response with a full-page reload. Either way, the screen would flash and the scripts and styles would need to get reloaded in a very non-turbo way.
Sure, the jQuery unobtrusive scripting adapter provided by
jquery-rails gives us access to binding to AJAX responses, but simply dumping a success or error response into the body doesn’t play nice with Turbolinks ability to preserve the browser’s state and history at these checkpoints of user activity. In search for a seemless solution, turboboost was born.
Design & Behavior
In order to bring AJAX control over our app’s forms in a Turbolinks compatible way, I defined some assumptions:
For GET requests, Turbolinks should visit the form’s action URL with the serialized data appended to it as a query string. This preserves navigable history states for things like live-updating search filter forms.
For other request types (POST, PUT, PATCH, DELETE, etc), an AJAX request should hit the Rails controllers. Then:
- If the response has a
redirect_todeclaration, do not reload. Instead, visit that route with Turbolinks.
- If there is an error, don’t visit anything with Turbolinks. Instead, the errors will be sent through the global document event
turboboost:error. Optionally, the errors can be prepended to the form as HTML.
- If the response has a
Turboboost only works on forms that you define with
turboboost: truein your Rails form helper options (ex:
form_for @post, turboboost: true do |f| ...) or manually with a
When a Turboform has an AJAX request in process, do sensible things like disable that form’s submit button.
In its simplest server-side implementation, a controller action would look like this:
1 2 3 4
If the post is invalid, a
turboboost:error event. If the post is successfully created, the app will visit the
post_url with Turbolinks if it was sent from a Turboform. Otherwise, the redirect will happen like normal.
You can also render the JSON error messages explicitly with the method
1 2 3 4 5 6 7 8 9 10 11
By default, Turboboost will render returned errors with the same HTML structure used in the default Rails generators and prepend it to the form. The structure looks like this:
1 2 3 4 5 6 7
Or this can be disabled and you can roll your own error handler:
1 2 3 4
There is also a
turboboost:success event that is trigger and passed a hash of the flash messages if they are present. You may also prevent redirecting on any Turboform by adding the attribute
data-no-turboboost-redirect to your form element if you just want to handle the response and returned flash messages manually: