DEV Community

Mary Webby
Mary Webby

Posted on

Data Integrity w/ Validations

Invalid Records History

Reminder: to run the rails console, you need to run either rails c or rails console in the terminal to prompt, even though it is pry you cannot just run pry in the terminal to get it started, you will need to run the other one to make sure that all you models and tables are being queried correctly.

  • As soon as you start serving data from external sources (ex. users, CSVs, or APIs) you have to start worrying about whether that data is valid

  • If you do encounter invalid records and they become apart of your database, you will have to begin writing your code defensively, utilizing if/elsif/else/end, just to guard against the invalid data.

  • It’s best not to allow invalid data that doesn’t meet our criteria to enter our database in the first place; then, we don’t need to worry about writing lots of defensive conditionals downstream in our code

  • ActiveRecord provides the feature: validations

  • Validations are a way that we can specify constraints on what we allow in each column in a model. It is crucial that we have the .save method, this will allow us not to place records into the database we don't want to. Thus, returning to us false

  • Validations are a super-useful tool that ActiveRecord provides for maintaining the integrity of our data.

How to Insert Validations in Models

question to address
let’s say we don’t want to allow any rows to enter our movies table with a blank director_id attribute.

how to fix & add validations
to address this problem we want to move into the Movie model insert a Validation inside of it.

class Movie < ApplicationRecord
  validates(:director_id, presence: true)

  def director
  # ...
end
Enter fullscreen mode Exit fullscreen mode
  • The first argument to validates is a Symbol; the name of the column we are declaring constraints for.

  • The second argument to validates is a Hash.

  • The keys in the Hash are the constraints we are applying. There is a fixed list of constraints built-in to ActiveRecord that we can choose from. By far, the three most common are :presence, :uniqueness, and :numericality.

  • the value that we are adding to either true, which would allow you wanting the simplest use of validation. On the other hand, you can also have a hash in there clarifying the configuration options, like whether you want want the :numerically validation to have maximum or minimum

Testing our New Validations with Tests

  • type these commands inot the rails console termnial

  • m = Movie.new creating a new instance of a movie

  • the return value should look something like this

[1] pry(main)> m = Movie.new
   (0.4ms)  SELECT sqlite_version(*)
=> #<Movie:0x00007f93ab387430
 id: nil,
 title: nil,
 year: nil,
 duration: nil,
 description: nil,
 image: nil,
 director_id: nil,
 created_at: nil,
 updated_at: nil>
Enter fullscreen mode Exit fullscreen mode
  • next, we will type m.save, which if done correctly should return a false

  • we can double check that its not in there by typing m into the console again to see that there was no created_at: or updated_at: values inserted so we know that it was never created.

    The Errors Collection

  • we can even find out why the object didn’t save. each ActiveRecord object has an attribute called errors, which contains an instance of ActiveModel::Errors — a collection of validation failures

  • we can then type m.errors into our terminal and ActiveModel::Errors will prompt an output like this

[4] pry(main)> m.errors
=> #<ActiveModel::Errors [#<ActiveModel::Error attribute=director_id, type=blank, options={}>]>
Enter fullscreen mode Exit fullscreen mode
  • next we can try to get the message
[5] pry(main)> m.errors.messages
=> {:director_id=>["can't be blank"]}
Enter fullscreen mode Exit fullscreen mode
  • there is also a very helpful method we can place onto the error which will return a list of arrays of detailed messages on how to fix our issue on why it is not saving.
[6] pry(main)> m.errors.full_messages
=> ["Director can't be blank"]
Enter fullscreen mode Exit fullscreen mode
  • later on down the road we can actually take those error messages, say in like logging in to an account or making a password and actually provide the user the string from the error to realize their mistakes and fix the issue. this is a good alternative than creating a for loop and making it so you have a ton of code. you can really be utilizing the ActiveRecord::Errors to make it so you are personally doing less code and using more resources.

Helpful Methods for Validations

  • validates(:something_id, presence: true) checks to see if a a specific "something" in a table has the presents of the thing it needs before saving to the table

  • validates(:something, uniqueness: true) checks to see if no other rows have the same value in that column, very helpful for usernames and stuff where each value has to be unique to the specific id so there is no confusion.

Top comments (0)