High Leverage Rails
Introduction
Introduction to this course
Why use Ruby on Rails
Why use SQLite
Ruby on Rails + SQLite
Powering Your App with SQLite
Creating tables
Timestamps
Column types
Typeof
Ruby types
Creating table introduction
Creating table advanced
Inserting data
Updating data
Upserting data
Reading data
Virtual columns
Enums
Introduction to JSON
Indexing JSON
JSON table functions
Building a Modern Rails Application
Creating a new Rails application
Installing Solid Queue
Installing Solid Cache
Installing Solid Cable
Dockerfile
Application overview
Authentication
Base styles
Registration
Scaffolding posts
Polishing posts
Scaffolding comments
Polishing comments
Polishing models
Polishing controllers
Creating new post
Updating post
Reviewing MVP
Tagging posts
Custom tags
Friendly URLs
Full text search
Deploying & Operating Your App
Backups
Check Litestream locally
Verifying backups
Deployment options
Deploying with Hatchbox
Deployment constraints
Vertical scaling
Database access
Migrations
Locked video

Please purchase the course to watch this video.

Video thumbnail
Building a Modern Rails Application
Polishing models

Full Course

$
129
$179
USD, one-time fee
This course came at the perfect time. I’ve recently gotten back into Rails after an 18-year hiatus, and this was a perfect refresher and shows just how much you can accomplish with Rails right out of the box.
Garrett Winder
Garrett Winder

Rails hosting made simple

Deploy apps to servers that you own and control.

Move fast and fix things

Application monitoring that helps developers get it done.

Summary

Learn how to set up model tests in Rails to validate associations, enforce constraints, and ensure data integrity. This video covers testing users, posts, comments, and sessions while implementing model-level validations and database constraints. With passing tests, we’re ready to move on to controller testing for authentication and authorization.

Video Transcript

Up until now, I haven’t talked much about tests, but they are an essential part of building a production-grade application.

I don’t strictly follow test-driven development (TDD), which is why I haven’t started with tests from the beginning. Instead, I like to lean on Rails scaffolds to quickly establish the core functionality and structure of the application. Then, once I have a clearer picture of the behavior I want, I begin encoding that behavior in tests.

In this video, we’ll start adding model tests and refactoring our models to ensure they pass. Let’s jump into the codebase and walk through the process.

Setting Up Model Tests

I’ve prepared standard model tests for our different models, covering:

Associations (e.g., ensuring models belong to the correct parent model) Validations (e.g., checking for required fields and uniqueness constraints)

Let’s go over them briefly before running the tests to see what fails and fixing any issues.

Session Model Test: The session model only needs a simple test to confirm that it belongs to a user.

User Model Test: We need to check that:

  1. The email address cannot be nil
  2. The email address must be unique

For uniqueness, we pull a fixture from the database, instantiate a new user, and assert that it fails validation due to an existing email.

Post Model Test: For posts, we verify:

  1. A post must have a title
  2. The title must be unique
  3. The title must be at least five characters long

Comment Model Test: For comments, we test:

  1. A comment must belong to a post
  2. The comment body cannot be nil
  3. The comment must be at least five characters long

Running and Debugging the Tests

Now, let's run the model tests:

bin/rails test test/models

We immediately see errors—this is expected because we haven’t added these validations to our models yet. Let’s go through and update each model accordingly.

Fixing User Model: We need to add the following validations:

validates :email_address, presence: true, uniqueness: true

After running the user model test again, it now passes successfully.

Fixing Session Model: No issues here—this test already passes because the association was correctly defined.

Fixing Post Model: The test errors confirm that our title validation is missing. We fix this by adding:

validates :title, presence: true, uniqueness: true, length: { minimum: 5 }

Running the post model test again—now it passes!

Fixing Comment Model: The test errors show that we need validations for the comment body. We add:

validates :body, presence: true, length: { minimum: 5 }

After re-running the comment model test, it also passes successfully.

Why Model-Level and Database-Level Validations Matter

While Rails model validations are powerful, I strongly believe in also defining database-level constraints whenever possible.

At the database level, we enforce:

  • Presence constraints (null: false)
  • Uniqueness constraints (unique indexes)

These ensure data integrity even if changes are made directly in the database. However, at the model level, Rails validations provide a better user experience by displaying clear error messages before data is ever sent to the database.

Some validations, such as minimum length requirements, make more sense to enforce at the model level rather than the database.

The Role of Tests in a Production-Ready Application

I don’t always start with tests, but as I define application behavior more clearly, tests become crucial for:

  • Ensuring correctness before deployment
  • Catching regressions as the app evolves
  • Providing confidence when making iterative improvements

With our model tests in place and passing, we now have a strong foundation for future changes. Let’s commit our work.

Up next, we’ll shift our focus to controller tests to validate authentication and authorization logic.