Using UUID as Primary Key in Rails4 With Postgres

UUID. means Universally Unique Identifier.

The original intent while creating UUIDs was to create distributed systems to uniquely identify objects without significant central coordination. Saying which means, anyone can create UUIDs and use them to identify something. There is a very high probability the same key will never be unintentionally created by anyone else to identify some other kind of object. Objects labeled with UUIDs can therefore be later merge into a single database without needing to resolve key/identifier(ID) conflicts.

Rails 4 gives native support for the type UUID in Postgres. In the following post I will explain how we can enable and use the UUID your Rails code.

First install postgresql and its helpful accompanying dependencies on your machine:

sudo apt-get install postgresql postgresql-contrib

Create rails application with database as postgresql

rails new testuuid --database postgresql

Bundle install. Now create a migration to enable_uuid_ossp_extension :

cd testuuid
bundle install
rails generate migration enable_uuid_ossp_extension

Change the migration and add following code to enable extension:

20140524055928_enable_uuid_ossp_extension.rb
1
2
3
4
5
class EnableUuidOsspExtension < ActiveRecord::Migration
  def change
    enable_extension 'uuid-ossp'
  end
end

That is it. Now we can use uuid as per wish in the code whichever model we want to in the follwing way :

rails generate model user name:string email:string description:string

Open the migration created for user and edit it to as:

20140524066666_create_users.rb (old)
1
2
3
4
5
6
7
8
9
10
11
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.string :email
      t.string :description

      t.timestamps
    end
  end
end
20140524066666_create_users.rb (new)
1
2
3
4
5
6
7
8
9
10
11
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users, id: :uuid do |t|
      t.string :name
      t.string :email
      t.string :description

      t.timestamps
    end
  end
end

We have to just change the column type from default integer to uuid by adding id: :uuid. Also for using uuid in foreign key columns use it as :

rails generate model post content:string user_id:integer
20140524066666_create_post.rb (new)
1
2
3
4
5
6
7
8
9
10
class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts, id: :uuid do |t|
      t.string :content
      t.uuid :user_id

      t.timestamps
    end
  end
end

Changing t.integer :user_id to t.uuid :user_id will do the magic. Every thing else will be handled by rails at behind the scenes. We can do :

User.create(name: 'Sahil', email: 'gr.sahil20@gmail.com')
User.first
User.last
User.count
u = User.where(email: 'gr.sahil20@gmail.com')
u.posts.create(content: 'Lorem Ipsum')

That was it for using uuid in rails with postgresql. Straight forward and simple :)

Comments