Validated by Built in Validations
Tags: ruby
Published: 2021-03-05 20:13:31

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.
```ruby
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.
```ruby
validates :username, presence: true
```
Alternatively, I could have also written it like this:
```ruby
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:
```ruby
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:
```ruby
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.
```ruby
class Note < ActiveRecord::Base
    belongs_to :user
    validates :content, presence: true
end
```
Easy. Now let's do the same for my equipment page.

```ruby
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.

```ruby
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