Rails + Postgres + UUID


  1. What the heck is UUID?
  2. Why would I want to use a UUID?
  3. Rails Setup
  4. DatabaseSetup
  5. The Big Reveal!
  6. Epilogue

A universally unique identifier (UUID) is a 128-bit number used to identify information in computer systems…While the probability that a UUID will be duplicated is not zero, it is close enough to zero to be negligible. — Wikipedia

Here’s an example:

Bad actors: and no, I don’t mean Steven Seagal and his perma-sunglasses face.

Steven Seagal gif where someone replaced a gun he was holding with an electric toothbrush
Mr. Seagal prepares to brush his teeth in public.

When you’re just using the straight-outta-the-box incremental integer IDs, a bad actor may be able to intuit quite a bit about your resources. It makes URL-hacking that much easier. If Mr. Seagal visits his user account page and peeps the URL that reads:


He might see that he’s user #13 and find that to be an unlucky number and leave the site. Seagal might think a site with only 13 users is embarrassing then tweet about it. He also might also see his messages page URL:


…and think to himself “Hmmm. I wonder if I can peep other people’s private messages by substituting those integer ids for other numbers that I think of while brushing my teeth.”

So yeah, we want to avoid people making too many inferences on our backend for some decent OpSec!

2016 image of person on plane typing into laptop wearing a knitted garment that obscures the screen and their hands
Mega secure with Becky Stern’s “Compubody Sock”

Go ahead and spin up a new Rails API with a Postgres database. PG is great for Heroku deployment especially since they don’t support Rails’ default database: SQLite

rails new app-with-uuid-keys --api --database=postgresql

Before we generate migrations for any of your models you’ll want to tell Rails that when generating migrations it should use uuid instead of plain old integers by creating this file:

Next you’ll want to generate your models/migrations for your Postgres database. But first we must enable the pgcrypto extension in our Postgres database:

rails generate migration enable_uuid --no-test-framework

This migration file should end up looking like this:

When generating your models if you specifically rails generate a model and not a migration then the Rails generator config that we set up moments ago will handle the uuid-ing of the user’s primary key.

Running rails g model user name:string email:string --no-test-framework generates a blank User model class annnnnd this beautiful migration:

database migration code showing the id as a uuid
Users migration table

Go ahead and run rails db:create && rails db:migrate

console printed text showing successful migrations of pgcrypto extension, users
This is what you should see!
GIF: Drag queen Violet Chachki on RuPaul’s Drag Race walking a runway and revealing a red garment from under a black one

If you call on your rails console in your terminal and create a User you’ll see that they’re being keyed with uuids instead of integers! Time to PARTY!! 🥳🥳🥳

Rails console readout that confirms id is uuid and not an integer

I will say that I did have some considerable frustration at one point in getting the hang of activating the pgcrypto extension. I was being foolish and manually creating the database from the Postgres macOS app without properly activating the extension. Which gave me fun errors like this:

a database error stating that function gen_random_uuid() does not exist

I eventually learned how to manually enable it in the terminal during my database doom spiral. You can paste this into your terminal while making sure to properly name your existing database: psql -d <database-name-here-no-carrots> -c ‘CREATE EXTENSION pgcrypto’

Again, not necessary if you let Rails do the heavy lifting with creation and migration of the database, but I’m glad I know this option exists!

Thanks for reading ❤




Full Stack Software Engineer. Multimedia performance engineer and performer. Through technology, I ❤ to bring ideas to reality–on the stage or in a browser.

Love podcasts or audiobooks? Learn on the go with our new app.

Hidden Reefs in String Pool, or Another Reason to Think Twice Before Interning Instances of String…

How to handle client errors gracefully with AppSync and Lambda

Coding as a Young Adult

Chapter 5 : New Listing Page

HADOOP CLUSTER TASK— Steps to Contributing limited storage as Slave Node to the cluster

What Are the Different Types of Bugs in Software Testing?

Lifecycle of a Process

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Dan Foley

Dan Foley

Full Stack Software Engineer. Multimedia performance engineer and performer. Through technology, I ❤ to bring ideas to reality–on the stage or in a browser.

More from Medium

Add Sidekiq and Redis to Ruby on Rails Application with Capistrano

Building a Ruby CLI app

Process PostgreSQL Changes With Logical Replication And Ruby


DISTINCT ON: A magic weapon for your queries