Learn Ruby on Rails Book

Using PostgreSQL

Using citext

Storing email in PostgreSQL using citext

Please note that devise gem is a very popular authentication gem in Rails community. devise gem automatically lowercases email before storing it in the database.

Using UUID as primary key

UUIDs are a popular alternative to auto-incremental integer primary keys. Using UUIDs as the id in your Rails models instead of incrementing integers helps you avoid collisions. The UUIDs are globally unique, meaning you can know that different models cannot possibly have the same id.

With an incrementing integer id the size of your data can be inferred from the outside i.e. id 5 is the fifth record created. With UUIDs no-one can guess the size of your database tables, which might be information you are keen to keep secret. You can get round this by generating ‘public ids’ or ‘slugs’ for exposed URLs… but then, why not use a built-in tool?

Ruby on Rails has had the ability to use UUIDs as the id for ActiveRecord models since version 5.0.

For PostgreSQL >= 9.4, ActiveRecord will now use pgcrypto’s gen_random_uuid function whereas previously uuid-ossp’s uuid_generate_v4 function was used.

Follow these steps to add UUID primary keys to your Rails 5.1 application.

Add a migration

First we need to enable the PostgreSQL pgcrypto extension in a migration. Lets start by creating a blank migration:

1rails generate migration enable_pgcrypto_extension

Then change the file to enable the extension. It should look something like this:

1class EnablePgcryptoExtension < ActiveRecord::Migration[6.0]
2  def change
3    enable_extension 'pgcrypto'
4  end

Change the primary default type

When you generate models ActiveRecord will use Integer as the type for id by default. From Rails 5 you can change this behaviour by adding the following to your config/application.rb file.

1config.generators do |g|
2  g.orm :active_record, primary_key_type: :uuid

This changes the default column type for primary keys, configuring your migration generator to set id: :uuid for new tables.

Now when you run rails generate model post title:string your migration file should look something like this:

1class CreatePosts < ActiveRecord::Migration[6.0]
2  def change
3    create_table :posts, id: :uuid do |t|
4      t.string :title
6      t.timestamps
7    end
8  end