Ruby on Rails 7 + Turbo - Not showing notice message

1.1k Views Asked by At

I am learning Ruby on Rails. Rails 7 + Turbo stream... I am following a tutorial and I am having a problem with displaying the Notice message.

Can you help me understand why I am not getting notice message after I create a new quote?

Here is a create action in QoutesController.rb. Only when I put this line of code:

flash[:notice] = "Gets displayed with this line and a refresh... "

before the format.html line, then I will get the notice message after I refresh the page upon creating a quote. Only then the message gets displayed. Can you please help me understand this?

(Yes, I am using a Devise gem here, Turbo stream, Turbo Rails, Rails 7)

Thank you

  def create
    @quote = current_company.quotes.build(quote_params)

    if @quote.save
      respond_to do |format|
        flash[:notice] = "Gets displayed with this line and a refresh... " #weird
        format.html { redirect_to quotes_path, notice: "Quote was successfully created." }
        format.turbo_stream
        #debugger
      end
    else
      render :new, status: :unprocessable_entity 
    end
  end
1

There are 1 best solutions below

1
On

In Rails 7, unrefresh page when you create successfully. So, flash[:notice] not display.

  1. Create views/shared
  2. In share folder, we have _flash.html.erb, _notices.html.erb

_flash.html.erb

<div class="alert <%= bootstrap_class_for(msg_type) %> alert-dismissible fade show" role="alert">
  <div class="container text-center">
    <%= message %>
    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
  </div>
</div>

_notices.html.erb

<div id="flash">
  <% flash.each do |msg_type, message| %>
    <%= render partial: "shared/flash", locals: { msg_type: msg_type, message: message } %>
  <% end %>
</div>

When you create success -> create views/qoutes/create.turbo_stream.erb

<%= turbo_stream.update "flash", partial: "shared/flash", locals: { msg_type: :notice, message: "your message" } %> 
// msg_type: :notice, :alert, :error, :success
  1. In views/layouts/application.html.erb
  <%= render 'shared/notices' %>
  <%= yield %>
  1. In application_helper
module ApplicationHelper
  def bootstrap_class_for(flash_type)
    {
      success: "alert-success",
      error: "alert-danger",
      alert: "alert-warning",
      notice: "alert-info"
    }.stringify_keys[flash_type.to_s] || flash_type.to_s
  end
end

and if create failed

ex:

def create
   if @object.save
      // code
   else 
      render_flash(:alert, full_messages(@post.errors.full_messages))
   end
end

In application_controller

class ApplicationController < ActionController::Base

   protected

    def render_flash type, message
      render turbo_stream: turbo_stream.update("flash", partial: "shared/flash", locals: { msg_type: type, message: message })
    end

    def full_messages messages
      messages.join("\n")
    end
end

=> This is my way. Hope to help you.