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">×</span>
</button>
</div>
<% end %>
I also tried:
flash.now[:success] = I18n.t('admin.settings.edit.success')
render :edit
Doesn't work either.
In Rails 7 turbo
expects POST / PUT / PATCH form submissions to redirect, usually that's create and update controller actions.
To render a template, the response has to have an invalid status, like :unprocessable_entity
, otherwise turbo shows an error in the browser console:
turbo.es2017-esm.js:2115 Error: Form responses must redirect to another location
at k.requestSucceededWithResponse (turbo.es2017-esm.js:679)
at A.receive (turbo.es2017-esm.js:450)
at A.perform (turbo.es2017-esm.js:431)
Rails 7 signup form doesn't show error messages
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 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, status: :unprocessable_entity
# 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
end
end
You can 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