# application.css
.field_with_errors {
color: red;
}
.field_with_errors input {
border-color: red;
}
# _form.html.erb
<%= form_with(model: user, local: true) do |form| %>
<% if user.errors.any? %>
<div class='alert alert-danger'>There was a problem with saving this form.</div>
<% end %>
<div class="form-group">
<%= form.label :first_name %>
<%= form.text_field :first_name, class: 'form-control' %>
<%= form.errors :first_name %>
</div>
<div class="form-group">
<%= form.label :last_name %>
<%= form.text_field :last_name, class: 'form-control' %>
<%= form.errors :last_name %>
</div>
<div class="form-group">
<%= form.label :age %>
<%= form.number_field :age, class: 'form-control' %>
<%= form.errors :age %>
</div>
<div class="actions">
<%= form.submit class: 'btn btn-primary' %>
</div>
<% end %>
# config/initializers/core_ext/form_builder/errors.rb
class ActionView::Helpers::FormBuilder
def errors(field_name)
if self.object.errors[field_name].present?
model_name = self.object.class.name.downcase
id = "error_#{model_name}_#{field_name}"
parent_id = "#{model_name}_#{field_name}"
string = %{
<label id=#{id} for="#{parent_id}" class="field_with_errors">
#{self.object.errors[field_name].join(', ')}
</label>
}
string.squish.html_safe
end
end
end
# models/user.rb
class User < ApplicationRecord
validates :first_name, presence: true
validates :last_name, length: { minimum: 2, maximum: 32 },
allow_blank: true
validates :age, inclusion: { in: 18..99, message: "must be 18+" },
length: { maximum: 2 }
end