'Flash is not displayed in the same view in Rails

I need to display flash in the same view (:edit) after successfully updating an object. If I redirect to another action - everything works correctly. But when I need to stay in :edit - doesn't work. Can someone explain to me what is my mistake... Thanks!

I have the following snippet of code in my controller:

  def edit
    @setting = Setting.find_by(slug: current_user)
  end

  def update
    @setting = Setting.find_by(slug: current_user)

    if @setting.update(settings_params)
      flash[:success] = I18n.t('admin.settings.edit.success')
    else
      flash[:danger] = I18n.t('admin.settings.edit.not_saved')
    end

    redirect_to edit_admin_setting_url(user: current_user)
  end

routes.rb:

scope ":user/" do
  namespace :admin do
    resource :setting, only: [:edit, :update]
  end
end

And edit.html.erb

      <% if flash[:success].present? %>
        <div class="<%= classes + "alert-success" %>">
          <%= icon("fas", "check") %>

          <%= flash[:success] %>

          <button type="button" class="close" data-dismiss="alert" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
      <% end %>

I also tried:

flash.now[:success] = I18n.t('admin.settings.edit.success')
render :edit

Doesn't work either.



Solution 1:[1]

That last bit of code you show

flash.now[:success] = I18n.t('admin.settings.edit.success')
render :edit

should work, assuming it actually rendered, I'm not sure where you placed it.

In rails 7 (or anywhere else), turbo expects update/create actions to redirect. To render a template, the response has to have an invalid status, like :unprocessable_entity, otherwise it shows an error in the browser console. https://stackoverflow.com/a/71762032/207090

You should also use rails generators to get a quick starting code and an example of how everything works.

bin/rails generate scaffold Sample name email
bin/rails db:migrate

This is one way to set up an update action:

# GET /:user/admin/setting/edit
#
# renders edit.html.erb
def edit
  @setting = Setting.find_by(slug: current_user)
end

# PATCH /:user/admin/setting
#
# redirects to user on success
# renders edit.html.erb on failure
def update
  @setting = Setting.find_by(slug: current_user)

  if @setting.update(settings_params)   # when setting updated

    flash[:success] = 'Success'         # set a message to show on the next request;
                                        # we have to redirect to another url

    redirect_to user_url(current_user)  # redirect some place else, like user profile
                                        # this means we're done with `update` action 
                                        # and with current request

  else                                  # when settings didn't update (validation failed)
                                        # we cannot redirect, because we'll loose our
                                        # invalid object and all validation errors
                                        # NOTE: sometimes if redirect is required
                                        #       errors can be assigned to `flash`

    flash.now[:danger] = 'Oops'         # set a message to show in this request; 
                                        # we have to render a response
                                        # NOTE: this might be unnecessary, because form 
                                        #       will also show validation errors

                                        # render edit.html.erb template,
                                        # this means we're staying in `update` action 
                                        # and in current request
                                        # NOTE: this has nothing to do with `edit` action at the top
    render :edit, status: :unprocessable_entity
  end
end

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1