Whenever there is a need to maintain records in a database, there is a need to validate data. Data validation cleanses the data before it is either input to or updated in an operation. There is an imminent need for cleansing data to maintain meaningful, high-quality valid data. Data validation also improves the security of data by filtering out malicious inputs.
Let’s look at an example:
Suppose you have an application for online shopping in which you are maintaining a database that stores the shipping address of the client. This means that when taking input from the client, you will have to ensure that the client has given a correct shipping address. Active Record Validation allows you to ensure this correctness. Rails makes it easy to use, provides built-in helpers for common needs, and allows you to create your own validation methods as well.
Active Record Objects are present either inside the database or outside of it. As a result, whenever there is a new input, we need to check whether or not that input is present in the database. If it is present in the database, then there is no need to validate it.
To check if data is present in a database, we can use .new_record?
, which returns a boolean value to signify if the data is already in the database. For example:
$ rails console
>> p = Person.new(name: "Michael Scofield")
=> #<Person id: nil, name: "Michael Scofield", created_at: nil, updated_at: nil>
>> p.new_record?
=> true
>> p.save
=> true
>> p.new_record?
=> false
In the code above, the name Michael Scofield is checked first to determine if it is present in the database. Since the check returned true
, the new entry is saved in the database. Upon calling new_record?
again, the check returns false
.
The bang versions (e.g., save!) raise an exception if the record is invalid. The non-bang versions don’t: save and update return false, and create just returns the object.
When the methods (specified above) that trigger validations are used in Rails,they will identify whether or not the task that was carried out is valid. If it is not valid, the .save
method will not be called.
Instead of implicitly relying on the validation to run automatically by the methods above, you can run validation yourself. Observe the following code:
class Person < ApplicationRecord
validates :name, presence: true
end
Person.create(name: "Michael Scofield").valid? # => true
Person.create(name: nil).valid? # => false
The above code is running Active Record Validation on :name
. It outputs true
if the input is a string; otherwise, it outputs false
.
To figure out what went wrong, there is a list of error messages saved when .valid?
returns false
. These error messages can be accessed using the .error.messages
method.
You can also use .invalid?
, which is the reverse of the .valid?
method.
Here are a few examples to get the hang of different validation methods used in Rails:
class Person < ApplicationRecord
validates :name, presence: true
end
>> p = Person.new
# => #<Person id: nil, name: nil>
>> p.errors.messages
# => {}
>> p.valid?
# => false
>> p.errors.messages
# => {name:["can't be blank"]}
>> p = Person.create
# => #<Person id: nil, name: nil>
>> p.errors.messages
# => {name:["can't be blank"]}
>> p.save
# => false
>> p.save!
# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
>> Person.create!
# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
To learn more about the Active Record Validation in Rails, check out the official guide.
Free Resources