ruby-on-railsflash-message

Flash message showing up again on clicking the back button in Rails


I am using flash hash to render prompts to user. It also contains a font-awesome icon so it renders something like this:

enter image description here

So the flash message renders properly but the issue is if I visit any other link on a page and then click the back button, it re-renders the flash message again.

Here's the logic behind rendering the flash message:

In application_controller:

class ApplicationController < ActionController::Base
  add_flash_types :success, :notice
end

In sessions_controller:

  def create
    user = User.find_by(its: params[:sessions][:its])
    if user&.authenticate(params[:sessions][:password])
      session[:user_id] = user.id

      respond_to do |format|
        format.all { redirect_to root_path(format: :html), success: t(".success") }
      end
    else
      flash.now.alert = t(".error")
      render :new, status: :not_found
    end
  end

In partial flash_messages:

<% if flash.any? %>
  <div id="flash" data-controller="autohide">
    <% flash.each do |name, msg| %>
      <%= render_flash_message(name, msg) %>
    <% end %>
  </div>
<% end %>

render_flash_message helper method:

  def render_flash_message(type, msg)
    content_tag :div, id: "flash-#{type}" do
      concat(content_tag(:i, "", class: "fa-circle-check"))
      concat(content_tag(:span, " #{msg}"))
    end
  end

I found some stack-overflow posts related to this:

  1. flash[:notice] is shown on browser back again
  2. Flash Message Stays After Leaving The Page And Returning Multiple Times
  3. How to show the flash message in Rails only once?

So as suggested by those answers, I have tried these:

  1. Use discard method.
  respond_to do |format|
    flash.discard[:success] = t(".success")
    format.all { redirect_to root_path(format: :html) }
  end

Result: Same behavior

  1. <% flash[name]=nil %> in my _flash_messages.html.erb
    <% flash.each do |name, msg| %>
      <%= render_flash_message(name, msg) %>
      <% flash[name]=nil %>
    <% end %>

Result: Ends up rendering new flash message with nil value and renders it on visiting next page

  1. Disabling Cache in application_controller.rb:
  before_action :set_cache_buster

  def set_cache_buster
    response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
    response.headers["Pragma"] = "no-cache"
    response.headers["Expires"] = "Mon, 01 Jan 1990 00:00:00 GMT"
  end

Result: This works but it expires all caches set in the application, resulting in more SQL queries

So the only solution that did work was setting cache to nil but that isn't something that I am looking for, so can anyone suggest any other solutions?

Thanks in advance! :)


Solution

  • Adding the data-turbo-temporary attribute to the flash block removes the element before the document is cached, preventing it from reappearing.

      <div id="flash" data-controller="autohide" data-turbo-temporary>
        <% flash.each do |name, msg| %>
          <%= render_flash_message(name, msg) %>
        <% end %>
      </div>
    

    Source