Migrations in Rails 8: Using the New Not Null Shortcut

In the latest version of Ruby on Rails (Rails 8), developers have been given a handy new shortcut for adding a NOT NULL constraint to database columns. This small but powerful enhancement simplifies the process of generating migrations, making them cleaner and more intuitive.

In this blog post, I’ll show how this new feature works and how it can help you create migrations faster.

What Is a NOT NULL Constraint?

Before diving into the new shortcut, let’s quickly revisit what a NOT NULL constraint is and why it’s important.

In a relational database, a column marked as NOT NULL ensures that no row can have a NULL value for that column. This constraint enforces data integrity by ensuring that important fields (like email, username, etc.) must always be filled in.

Without this constraint, there’s a risk of unintentionally leaving critical fields blank, leading to potential bugs and broken business logic.

The Old Way: Rails Migrations in Previous Versions

In Rails 7 and earlier versions, you would typically generate a migration and then add the null: false option to each column manually. Here’s how it looked:

1
2
3
4
5
6
class AddDetailsToUsers < ActiveRecord::Migration[7.0]
  def change
    add_column :users, :email, :string, null: false
    add_column :users, :username, :string, null: false
  end
end

This worked, but having to manually specify null: false for every NOT NULL column could be repetitive and error-prone.

The New Rails 8 Way: ! in the Generate Command

In Rails 8, you can simplify this process when generating migrations. Instead of manually adding null: false in the migration file, you can now append an exclamation mark (!) when running the rails generate migration command. This automatically adds the NOT NULL constraint for you.

Example

Instead of writing this:

1
rails generate migration AddDetailsToUsers email:string username:string

And then modifying the generated migration to add null: false, you can now do:

1
rails generate migration AddDetailsToUsers email:string! username:string!

This command will generate a migration with the NOT NULL constraint automatically applied to the email and username columns.

Here’s what the migration file will look like after using this shortcut:

1
2
3
4
5
6
class AddDetailsToUsers < ActiveRecord::Migration[8.0]
  def change
    add_column :users, :email, :string, null: false
    add_column :users, :username, :string, null: false
  end
end

Notice that the null: false constraint is added automatically because of the ! used in the generate command.