Primary Keys as UUIDs: A Guide
When first getting started with programming in Rails, a new dev will learn about how classes are created implicitly with sequential ids. Sequential ids are nice because they’re easy on the eyes and it’s even easier to track stuff down within your json.
Sequential ids do have their drawbacks. Take this endpoint for example:
Following RESTful practices, this URL should bring us to a show page for the user with the id of 3. The largest issue here is how exposed our URI is. If our URLs have exposed URIs, it’s easier for people to access data and that’s never a good thing. Enter UUID.
UUIDs are a random collection of letters and numbers that create an almost salted id for us. I was really surprised with how easy the implementation is in Rails 6 and I think you will be, too!
Step 1: Create a Migration for UUIDs
Once you’ve gone ahead and created a new rails application, it’s time to run a migration to help us set up our UUIDs. PostgreSQL knows how to use UUIDs this way, so be sure to change your database from the default!
rails g migration enable_uuid
This will set us up with a migration file in our database. Next, add the enable_extension ‘pgcrypto’ to the change method.
Step 2: Set UUID as Primary Key Type
As mentioned earlier, our primary keys are set to sequential ids by default. Let’s see how we would handle changing this in one of our models.
Now when we’re creating our table, we’re going to establish that the id for each report will be a uuid. In this model relationship, a Device has_many Reports, so we’ll need to make sure to say that our foreign key is also a uuid instead of the typical t.integer. Now when we migrate our models and look at our schema.rb file…
…our default for our id will generate a random uuid. Now our reports and devices both have uuids!
A Single Caveat
As you can see, it’s really easy to establish UUIDs as your primary keys. There is one drawback and that’s that the order of your instances will likely become out of order. This is because Rails will sort UUIDs alphabetically, so if your second instance starts with ‘a’, it will likely show up as your first instance. Numbers, in this case, go after letters, so you’ll need to figure out a way to re-sort your instances by something else (created_at, maybe?)