All Rails built-in validators populate the details hash with the appropriate validator type.
errors[:base]
You can add error messages that refer to the state of the object as a whole rather than to a single attribute. This method can be used if you want to say that an object is invalid, regardless of the values of its attributes. Since errors[:base] is an array, you can simply add a string to it and it will be used as the error message.
classPerson < ApplicationRecord
def a_method_used_for_validation_purposes
errors[:base] << “This person is invalid because …”
end
end
errors.clear
The clear method is used when you intentionally want to clear all messages in the errors collection. Naturally, calling errors.clear on an invalid object won’t actually make it valid: right now, the errors collection will be empty, but the next time you call valid? or any method that tries to save that object to the database, the validations will run again. If any of the validations fail, the errors collection will be populated again.
classPerson < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
person = Person.new
person.valid? # => false
person.errors[:name]
# => [“can’t be blank”, “is too short (minimum is 3 characters)”]
person.errors.clear
person.errors.empty? # => true
person.save # => false
person.errors[:name]
# => [“can’t be blank”, “is too short (minimum is 3 characters)”]
errors.size
The size method returns the number of error messages for the object.
classPerson < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
person = Person.new
person.valid? # => false
person.errors.size # => 2
person = Person.new(name: “Andrea”, email: “[email protected]”)
person.valid? # => true
person.errors.size # => 0
(displaying-validation-errors-in-the-view) Display validation errors in views
Once you’ve created a model and added validations, if that model is being created with a web form, then you might want to display an error message when one of the validations fails.
Because each application handles this kind of thing differently, Rails doesn’t have a view helper to generate these messages directly. However, thanks to the rich set of methods, Rails in general gives a way to interact with validations, it’s very easy to create your own. Also, when generating a scaffold, Rails will place some ERB in the _form.html.erb generated to display the complete list of errors for that model.
Let’s say we have a model stored in the @article instance variable, it looks like this:
<% if @article.errors.any? %>
<div id=”error_explanation”>
<h2><%= pluralize(@article.errors.count, “error”) %> prohibited this article from being saved:</h2>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Moreover, when using Rails form helpers to create forms, when a field has a validation error, an extra <div> is generated around the content.
<div class=”field_with_errors”>
<input id=”article_title” name=”article[title]” size=”30″ type=”text” value=””>
</div>
This div can be styled however you like. For example, the default scaffold that Rails generates adds this CSS rule:
.field_with_errors {
padding: 2px
background color: red
display:table;
}
This means that any field with an error has a 2 pixel red border around it.
Active Record Callbacks
This guide will teach you how to intervene in the lifecycle of your Active Record objects.
After reading this guide, you will know:
About the lifecycle of Active Record objects
How to create callback methods that respond to events in the life cycle of an object
How to create special classes that encapsulate common behavior for your callbacks
Object lifecycle
As a result of the normal operations of a Rails application, objects can be created, updated, and destroyed. Active Record gives you the ability to intervene in this object lifecycle so you can control your application and its data.
Validations allow you to be sure that only valid data is stored in your database. Callbacks allow you to switch logic before or after an object’s state changes.
Callback Overview
Callbacks are methods that are called at specific points in an object’s life cycle. With callbacks, it is possible to write code that will be run when an Active Record object is created, saved, updated, deleted, validated, or loaded from a database.
Registering callbacks
In order to use the available callbacks, they must be registered. You can implement callbacks as normal methods and then use class macro methods to register them as callbacks.
class User<ApplicationRecord
validates :login, :email, presence: true
before_validation :ensure_login_has_a_value
private
def ensure_login_has_a_value
if login.nil?
self.login = email unless email.blank?
end
end
end
Class macro methods can also receive a block. They can be used if the code inside the block is so short that it fits on one line.
class User<ApplicationRecord
validates :login, :email, presence: true
before_create do
self.name = login.capitalize if name.blank?
end
end
Callbacks can also be registered to execute on certain lifecycle events:
class User<ApplicationRecord
before_validation :normalize_name, on: :create
# :on also takes an array
after_validation :set_location, on: [ :create, :update ]
private
def normalize_name
self.name = name.downcase.titleize
end
def set_location
self.location = LocationService.query(self)
end
end
It is considered good practice to declare callback methods private. If left public, they can be called from outside the model and violate the principles of object encapsulation.
Available callbacks
Here is a list of all available Active Record callbacks, listed in the order they are called during their respective operations:
Create an object
before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save
after_commit/after_rollback
Object update
before_validation
after_validation
before_save
around_save
before_update
around_update
after_update
after_save
after_commit/after_rollback
Object destruction
before_destroy
around_destroy
after_destroy
after_commit/after_rollback