render builds the response from a template within the current request, while redirect_to tells the browser to send a new request to another URL.
render :new shows the new template without running the new action. Instance variables from the current action, like @user with its errors, stay available to the view.
redirect_to @user sends a 302 response with the new URL. The browser then requests that page, so the target action runs from the start and the old instance variables are gone.
def create
@user = User.new(user_params)
if @user.save
redirect_to @user # New request to show action
else
render :new, status: :unprocessable_entity # Renders new template with @user errors
end
end
That gives the usual pattern for forms. After a successful save, redirect, so refreshing the page does not submit the form again. After a failed save, render the form again with status 422. Turbo, the JavaScript library new Rails apps include since Rails 7, only shows a form response that redirects or carries an error status.
Rewriting in plainer words…
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
The diagram below the answer is the concept .
Jump to it ↓
Tailored explanation · switch back to · ·
What should the new diagram focus on?
See it - interactive diagram
render vs redirect_to: one request or two
Browser
Rails app
Save fails: POST /users
⟲ render :new
422 + form with errors
Save succeeds: POST /users
302, Location: /users/1
GET /users/1
⟲ show runs from the start
200 + user page
1step
The create action runs. @user.save returns false, so @user now holds the errors.
1 / 8← → keys
render answers the same request, so @user keeps its errors. redirect_to makes the browser send a new request, so the show action starts without any of create's instance variables.