Sebastian's dev blog 

Hard refresh is the Rails way

How I stopped worrying and learned to love the hard refresh

Background

At RailsConf 2025 in Philadelphia I joined a hack space and worked on an issue for mission_control-jobs, the front end dashboard for managing SolidQueue jobs

The problem

As a good first issue, I tried solving a bug where setting a filter for Job class then discarding the job would lead to the filter being lost in the redirect!
before-discard-job-dashboard.png 391 KB

after-discarding-job-filter-clears.png 366 KB
Solve by saving params or turbo streams?

The filter is first set when entering the job class name in the search field, which submits automatically with the job_class_name parameter. It was lost on discard because the discard button submitted without the job_class_name parameter. The most straightforward solution is to ensure the current job_class_name is included into the discard button's job_discard_path params. (See end of article for solution)

Two other developers paired with me on this and we thought a nice way to solve this would be with turbo streams: remove the listed job element from the page and use turbo streams to discard the job in the controller:
format.turbo_stream { render turbo_stream: turbo_stream.remove("job_#{@job.job_id}") }

That would clear the jobs without a hard refresh. More user friendly than refreshing the page. Sounds awesome right?
wrong.png 204 KB

In this article we'll find out why the solution with turbo has more drawbacks than benefits.
Turbo requires maintenance by the developer to ensure an accurate data state is shown to the user. Secondly, turbo wont do anything if your server is down. This should convince you that a standard form submit is the Rails way!

UI state becomes difficult when discarding a job with turbo

Yuri pointed out, that there was another element we needed to target in our turbo stream, which is the "job_class_count jobs count" element. The solution with turbo discarding the element does not update the count. This adds another required step to our turbo stream that needs to fetch the latest count for that job class from the server and update the jobs count element.
jobs-count-element.png 191 KB

Imagine in the future we're adding more data for display, the turbo stream will need to be updated, as it's coupled to the view and the data it presents.

Another state the developer now needs to handle is the "Job discarded" flash message. Previously rails rendered the flash message upon refresh. However with turbo, entire gems have been written to solve this problem (see: joshmn/hotflash)

A discard button with a default form submit would refresh the page and the jobs count would be correct, you would see the correct flash message, and no extra maintenance is needed as the jobs dashboard view gets updated.

Turbo when the server is down

If the server is down, the discard turbo stream will do nothing, if you check the browser console you will see a network error from turbo, other than that no clue what's wrong.
With default form submission, upon the first discard action, the user will see "site cant be reached". You would have to add separate javascript polling method to check that the server is still running and display a message to the user if it's online or down. 

Maybe a polling HTML element would be a nice component modern browsers could support!

Hard refresh is the Rails way

The solution of passing the existing parameters to the discard button to persist state means developers have less code to maintain, and can put their trust in Rails rendering the page. This is why the hard refresh is the Rails way.

Solution:

app/views/mission_control/jobs/jobs/failed/_actions.html.erb
@@ -1,5 +1,5 @@
 <div class="buttons is-right">
-  <%= button_to "Discard", application_job_discard_path(@application, job.job_id), class: "button is-danger is-light mr-0",
+  <%= button_to "Discard", application_job_discard_path(@application, job.job_id, params: params.permit!), class: "button is-danger is-light mr-0",
     form: { data: { turbo_confirm: "This will delete the job and can't be undone. Are you sure?" } } %>
...

updated: 2025-07-22 14:41:25 UTC
back to Web Development more tutorials
admin login