Validations


Collapse Content

Your console store app can be used to perform all sorts of actions, including ones that shouldn't be valid. For example, let's say we create a product in the rails console without any information in it:

prod = Product.create

This outputs:

 (0.2ms)  begin transaction
  SQL (0.7ms)  INSERT INTO "products"...
   (1.4ms)  commit transaction
 => #<Product id: 9, name: nil, description: nil, price: nil, ... > 

This just saved a product to the database with no values filled in. This is not only useless, it can cause bugs when other code expects certain values to exist in a product, such as a product's name. Go ahead and destroy the product just created:

prod.destroy

To prevent an invalid product from being created, we should add code to validate our data before it is saved. Rails provides a validates method for this purpose. Add the validates line to your Product model:

class Product < ActiveRecord::Base
  validates :name, presence: true

 belongs_to :category
end

The validates method takes in parameters for the column and the property you're ensuring, such as the name and presence.

Now that we've ensured every product will have a name, let's make sure every product has a price. Enter the code to do that below and in your Product class.

Terminal Time

Reload your console and try to create an empty product like before.

Product.create

Output:

(0.1ms)  begin transaction
(0.1ms)  rollback transaction
...

The database transaction has been rolled back since the validations failed. You can also make Rails throw an Error when an invalid transaction is attempted. To do this, just add a ! to create:

Product.create!

This will return the following:

(0.1ms)  begin transaction
(0.1ms)  rollback transaction
ActiveRecord::RecordInvalid: Validation failed: Name can't be blank, Price can't be blank.

These validation messages are often useful for knowing what's wrong with a given entry. Let's create another product without saving it to the database:

prod = Product.new
 => #<Product id: nil, name: nil, description: nil, price: nil, created_at: nil, updated_at: nil, category_id: nil> 

You can use the valid? method to check if a product is valid:

prod.valid?
 => false 

If it's not valid, you won't be able to save it:

prod.save
 (0.2ms)  begin transaction
 (0.1ms)  rollback transaction
 => false 

Now let's fix the product so we can save it:

prod.name = "Tomato"
 => "Tomato" 
prod.price = 1
 => 1 
prod.valid?
=> true
prod.save
 INSERT INTO "products"...
  (2.2ms)  commit transaction
 => true 

The new valid product has been saved to the database!

With basic validations in place, we can ensure invalid products don't get added to the database.

Advanced validation

No products should have a price less than 0, or your store could end up owing money to people who buy things! To prevent this from happening, create a validation that prevents price from going below 0.

Go to the Rails Guide on Validations to find the syntax to use. This line is somewhat complex, you will need to pass in an option to the validation helper. Check the hint below if for some more help.

Challenge

Enter the code to ensure every product has a price.

Please sign in or sign up to submit answers.

Alternatively, you can try out Learneroo before signing up.

Challenge

Write the validation that will ensure :price is greater than or equal to 0.

Please sign in or sign up to submit answers.

Alternatively, you can try out Learneroo before signing up.

Contact Us
Sign in or email us at [email protected]