Rails + Postgres + UUID
- What the heck is UUID?
- Why would I want to use a UUID?
- Rails Setup
- The Big Reveal!
1. What the heck is UUID?
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:
2. Why would I want to use a UUID?
Bad actors: and no, I don’t mean Steven Seagal and his perma-sunglasses face.
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!
3. Rails Setup
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.
rails g model user name:string email:string --no-test-framework generates a blank
User model class annnnnd this beautiful migration:
4. Database Setup
Go ahead and run
rails db:create && rails db:migrate
5. The Big Reveal
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!! 🥳🥳🥳
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:
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 ❤