Goal
You’ll be able to use flash messages and redirects correctly together, and understand why flash specifically persists across exactly one redirect — a detail that explains behavior beginners often find confusing.
Learn
After a create, update, or destroy action, it’s standard practice to redirect the user (rather than directly rendering a view), often with a flash message confirming what happened:
def create
@product = Product.new(product_params)
if @product.save
redirect_to @product, notice: "Product was successfully created."
else
render :new
end
end redirect_to sends the browser a genuinely new request to a different URL, rather than directly rendering a view in response to the current request. flash[:notice] (or flash[:alert] for errors) stores a message that survives exactly one redirect, then automatically clears itself.
Here’s the genuinely important reason redirect (rather than directly rendering) is standard practice after a successful create/update/destroy: it prevents a real, well-known problem where refreshing the page after a form submission would resubmit the exact same form data again, potentially creating duplicate records. Redirecting sends the browser to a fresh GET request instead, so refreshing that page just re-requests the same safe GET, not the original POST.
Note the pattern in the example: on success, redirect_to (with a flash message); on validation failure, render :new directly (re-displaying the form with its existing errors, no redirect) — this distinction matters, since a failed validation genuinely needs to show the user’s original input and errors again, which a redirect (a fresh new request) would lose entirely.
Decision Task
After a successful product creation, a developer considers using render :show instead of redirect_to @product. Before reading on: what real, practical problem could this create if the user then refreshes the page?
Show Answer
Refreshing after a rendered response (rather than a redirect) would resubmit the exact same original POST request, potentially creating a duplicate product record. Using redirect_to instead sends the browser to a genuinely new GET request; refreshing that page just re-requests the same safe GET, not the original form submission — exactly why redirect is the standard, safer practice after a successful create/update/destroy.
Common Mistake
Using render instead of redirect_to after a successful create, update, or destroy action. This creates real risk of duplicate form resubmission if the user refreshes the page afterward, since render doesn’t send the browser a new request the way redirect_to does — the browser would simply resubmit whatever the original request was on refresh.
Practice Questions
1. Write a redirect after successfully updating a record, including a flash notice message.
Show Answer
redirect_to @product, notice: "Product was successfully updated."
2. Why does render :new (not redirect) make sense specifically when validation fails, unlike the success case?
Show Answer
The user’s original input and validation error messages need to be shown again on the same form; a redirect (a fresh new request) would lose that data entirely, while render preserves it since it’s handling the same original request.
3. What real problem does redirecting (rather than rendering) after a successful create specifically prevent?
Show Answer
Duplicate form resubmission if the user refreshes the page — redirecting sends a fresh GET request, so refreshing just re-requests that safe GET rather than resubmitting the original POST.
4. True or False: flash messages persist indefinitely until manually cleared.
Show Answer
False — flash messages specifically persist across exactly one redirect, then automatically clear themselves.
5. What’s the difference between flash[:notice] and flash[:alert], in typical convention?
Show Answer
They’re both flash message types with no genuinely different mechanism — notice is conventionally used for success messages, alert for error/warning messages, though this is a naming convention, not an enforced technical distinction.
Try It Yourself
Without looking back, write a destroy action that deletes a record and redirects to the index page with an appropriate flash notice.
Show Answer
def destroy\n @product = Product.find(params[:id])\n @product.destroy\n redirect_to products_path, notice: "Product was successfully deleted."\nend
Quick Check
1. What does redirect_to do, compared to rendering a view directly?
Show Answer
Sends the browser a genuinely new request to a different URL, rather than directly rendering a view for the current request.
2. How long does a flash message persist?
Show Answer
Across exactly one redirect, then it automatically clears.
3. What real problem does redirecting after a successful create prevent?
Show Answer
Duplicate form resubmission if the user refreshes the page afterward.
4. Why does a failed validation typically use render :new instead of a redirect?
Show Answer
To preserve and re-display the user’s original input and validation errors, which a redirect (a fresh request) would lose.
5. What’s the conventional difference between flash[:notice] and flash[:alert]?
Show Answer
notice is conventionally used for success messages, alert for errors/warnings — a naming convention, not an enforced technical rule.