Validated by Built in Validations
kevhines
Posted on March 5, 2021
Working on a simple Sinatra MVC app for my Flatiron Project I needed to validate a number of fields. It was so easy thanks to the many built in validation methods inherited from ActiveRecord.
My project is a webpage that allows a user to create a character, and then enter equipment held by that character and/or notes about the campaign. (Both notes and equipment can be marked as private, otherwise they are all visible to all users)
Password Validation
The first validation I needed was to make sure the user entered a password. (for this simple project I don't require any additional rules on the password, so you can finally use your favorite password: 12345).
This validation is easy because of the bcrypt gem. In my User model I just entered the macro: has_secure_password. This encrypts the password and also requires the user to enter one on sign up. It also helps with authentication later on.
class User < ActiveRecord::Base
has_many :notes
has_many :goods
has_secure_password
end
Picky UserName Validations
But I had other requirements. I didn't want UserNames to have spaces in them or to have special characters. They aren't ever seen and I wanted to keep them simple.
First I required the presence of username with this macro.
validates :username, presence: true
Alternatively, I could have also written it like this:
validates_presence_of :username
But as I mentioned I wanted to keep spaces and special characters out of my user name. So I used the first version because it took in more attributes for validation. To keep out spaces and special characters I used the format attribute. With a little help from a regular expression it looked like this:
validates :username, presence: true, format: { with: /\A\w+\z/, message: "doesn't allow spaces or special characters" }
In addition I didn't want users to have the same usernames, so I needed to make sure they were unique. Just to be extra clear I didn't want users to have usernames that were identical except for different cases (ex. User1: Texas -- User2: texas). Both of these could be checked with the validation helper which has a case_sensitive attribute.
So my final validation was:
class User < ActiveRecord::Base
has_many :notes
has_many :goods
has_secure_password
validates :username, presence: true, format: { with: /\A\w+\z/, message: "doesn't allow spaces or special characters" }, uniqueness: { case_sensitive: false }
end
More Validations
Great. Now let's make sure that when users create notes they don't save blank content.
class Note < ActiveRecord::Base
belongs_to :user
validates :content, presence: true
end
Easy. Now let's do the same for my equipment page.
class Good < ActiveRecord::Base
belongs_to :user
validates :name, :quantity, presence: true
end
Oh wait. I don't want people entering non-numbers for quantity. I don't do any calculations with that value but it just wouldn't make sense. In fact I don't want decimals either. No one carries 1.3 swords. So let's use another built in validation macro.
class Good < ActiveRecord::Base
belongs_to :user
validates :name, :quantity, presence: true
validates_numericality_of :quantity, only_integer: true
end
These are so easy. Now my code just has to grab the error messages and send them to the user so they know why their Equipment, Note or Signup didn't save.
Further Reading
There are many other validation helpers. You can validate a specific length or length range. You can validate presence on update (allowing large forms to require only truly necessary pieces at first but on later updates require more values to be entered). You can not allow certain text strings (maybe you have an email field and you want to exclude people still using hotmail. You can set that up!). So many easy validations are already defined by these macros!
Read more about it here: https://guides.rubyonrails.org/active_record_validations.html#validation-helpers
Posted on March 5, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024