How to Display Validation Errors in Form in Ruby on Rails
In Ruby on Rails, display validation errors in a form by using the
form_with helper combined with model.errors.full_messages to show error messages. You can use form_with along with custom code to list errors above the form fields.Syntax
Use form_with model: @model to create a form bound to a model instance. Inside the form, check @model.errors.any? to see if there are errors. Use @model.errors.full_messages to get an array of error messages to display.
This pattern helps show validation errors after a form submission fails.
erb
<%= form_with model: @user do |form| %> <% if @user.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2> <ul> <% @user.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div> <%= form.label :name %> <%= form.text_field :name %> </div> <div> <%= form.label :email %> <%= form.email_field :email %> </div> <div> <%= form.submit %> </div> <% end %>
Example
This example shows a simple user form that displays validation errors if the user submits invalid data, such as missing name or email.
ruby,erb
# app/models/user.rb class User < ApplicationRecord validates :name, presence: true validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP } end # app/controllers/users_controller.rb class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(user_params) if @user.save redirect_to root_path, notice: "User created successfully" else render :new end end private def user_params params.require(:user).permit(:name, :email) end end # app/views/users/new.html.erb <%= form_with model: @user do |form| %> <% if @user.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2> <ul> <% @user.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div> <%= form.label :name %> <%= form.text_field :name %> </div> <div> <%= form.label :email %> <%= form.email_field :email %> </div> <div> <%= form.submit "Create User" %> </div> <% end %>
Output
<form action="/users" method="post">
<div id="error_explanation">
<h2>2 errors prohibited this user from being saved:</h2>
<ul>
<li>Name can't be blank</li>
<li>Email can't be blank</li>
</ul>
</div>
<div>
<label for="user_name">Name</label>
<input type="text" name="user[name]" id="user_name" />
</div>
<div>
<label for="user_email">Email</label>
<input type="email" name="user[email]" id="user_email" />
</div>
<div>
<input type="submit" value="Create User" />
</div>
</form>
Common Pitfalls
- Forgetting to check
@model.errors.any?before displaying errors can cause empty error blocks. - Not rendering the form with the invalid model instance after a failed save means errors won't show.
- Using
form_taginstead ofform_with model:loses automatic error binding. - Not permitting parameters correctly in the controller can cause validation to fail silently.
erb
<!-- Wrong: Not checking errors --> <%= form_with model: @user do |form| %> <div id="error_explanation"> <ul> <% @user.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <!-- form fields --> <% end %> <!-- Right: Check errors before showing --> <%= form_with model: @user do |form| %> <% if @user.errors.any? %> <div id="error_explanation"> <ul> <% @user.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <!-- form fields --> <% end %>
Quick Reference
- Use
form_with model: @modelto bind form to model instance. - Check
@model.errors.any?before displaying errors. - Use
@model.errors.full_messagesto get readable error messages. - Render the form with the invalid model instance after failed save to keep errors visible.
- Permit parameters correctly in the controller to avoid silent failures.
Key Takeaways
Always use
form_with model: @model to bind forms to models for automatic error handling.Check
@model.errors.any? before showing error messages to avoid empty error blocks.Display errors using
@model.errors.full_messages inside the form for clear feedback.Render the form with the invalid model instance after a failed save to keep errors visible.
Permit parameters properly in the controller to ensure validations run correctly.