Let's see how to work with uuids in Rails. First of all, have in mind this is
not the default in Rails, but it should be fine/easy to implement.
Use it in both sides
We needed to use UUIDs in one of our projects. Our front-end application was
generating UUIDs and we wanted to use it also in our back-end.
Using UUIDs helps us not having a centralized id generation. We don't need to
rely on just one place to create resources.
Imagine you have this scenario: a react application creating and editing
resources and a Rails API. The React Application communicates with the back-end. It needs to have local IDs before persisting data, in order to reference relationships ahead of time, and it creates a large graph of objects at once.
Should you have different IDs for both sides? No, you don't need that. You can
Enable the extension
Previously the extension you needed was
So, depending in which Postgres version you're using, you can create a migration
to enable this extension. In our case, we will enable both.
rails migration EnableUuidExtension
And our migration will look like:
class EnableUuidExtension < ActiveRecord::Migration[5.1]
The next thing is to use the uuid in one of our models. We can do that in two ways:
class CreatePerson < ActiveRecord::Migration[5.1]
create_table :people, id: false do |t|
t.uuid :id, null: false
add_index :people, :id, unique: true
In this case, we are using
id:false in our create_table and we are setting the
uuid. We are also creating the index here for our
id and setting the id to not be null. In order to create the uuid, you could create a
before_create and every time it creates a new object you could set the uuid.
class CreatePeople < ActiveRecord::Migration[5.1]
create_table :people, id: :uuid do |t|
In this case, we are passing
id: :uuid in the
create_table and we don't need
to pass the
id inside of the block. Doing that, it generates a uuid every time
you create a new object. This should be a normal way to use uuids.
If we try to create a new person, you can see it generates a new uuid for that:
irb(main):002:0> p = Person.create
SQL (2.2ms) INSERT INTO "people" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2017-07-14 03:06:32.697148"], ["updated_at", "2017-07-14 03:06:32.697148"]]
=> #<Confirmation id: "886bb121-bd76-4199-9dcb-ce40e0164edf", name: nil, created_at: "2017-07-14 03:06:32", updated_at: "2017-07-14 03:06:32">
Now, imagine you have set up uuids in your Rails application, and you want to
And you try to create a new Person and you pass a uuid
irb(main):001:0> p = Person.new(id: '123')
=> #<Person id: nil, name: nil, created_at: nil, updated_at: nil>
Doing that, you can see the person didn't get the id. Why did this happen?
This is because ActiveRecord
if the id matches the regular expression. As we are using uuids, it should be a
real uuid and not
123. Thanks Rafael Sales to point me out this!
Right now, if we try to pass a uuid to our object, it should work.
irb(main):003:0> p.id = SecureRandom.uuid
I hope this post helps you see how simple it is to use uuids in Rails.