PostgreSQL UUID primary keys in Rails 5

9379e0f68d34f1973b728c1b069135b2?s=106 Published on by Rails, PostgreSQL, and Ruby

In a recent project I have been using UUIDs as the primary key type with Rails 5 and PostgreSQL. This can be useful if your objects IDs are publicly exposed and you want to disguise the fact that they are a sequence, or how early on in the sequence they might be ;-)

How to make it happen...

First you need to enable the uuid-ossp extension which will generate secure v4 UUIDs in the database.

$ bin/rails g migration enable_uuid_extension
class EnableUuidExtension < ActiveRecord::Migration[5.0]
  def change
    enable_extension 'uuid-ossp'
  end
end

Next up you want to setup a generator so that rails sets all primary key columns to be UUID by default.

# config/initializers/generators.rb

Rails.application.config.generators do |g|
  g.orm :active_record, primary_key_type: :uuid
end

And that’s all you need to use UUIDs as your primary key. Thanks to Jon McCartie.

Foreign key references

If you get an error trying to run migrations for foreign keys make sure to set the type to :uuid

# example foreign key constraint
t.references :web_page, foreign_key: true, type: :uuid

Adding non primary key UUIDs

You may want to add UUID columns in other places. As long as you’re using uuid_generate_v4() you can use UUIDs as API keys or secure tokens for user lookup. This allows you to have postgres handle generation of these values for you, keeping your Rails app leaner.

class AddSecureTokenToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :secure_token, :uuid, null: false, default: 'uuid_generate_v4()'
    add_index :users, :secure_token, unique: true
  end
end

I hope this has been useful and if you have anything to add drop a comment below.

Related Articles

It seems like the whole world over is getting ready for GDPR to hit and with 10 days to go if you’re still under pressure here’s something that might help.

A standalone websocket server written in Crystal. It’s easy to use and works with any server-side language that can use JSON Web Tokens. You can find the Bifröst server on Github and if you’re using Ruby we have a companion gem to help your server-side code talk to Bifröst.

This is another post coming out of working on one of our products, https://voidapp.co. You often see articles teaching testing or TDD on an example topic, so I thought it was time to start writing about real world testing, with real code.