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.
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] def change enable_extension 'uuid-ossp' enable_extension 'pgcrypto' end end
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] def change create_table :people, id: false do |t| t.uuid :id, null: false t.string :name t.timestamps end add_index :people, :id, unique: true end end
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] def change create_table :people, id: :uuid do |t| t.string :name t.timestamps end end end
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 (0.2ms) BEGIN 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"]] (1.9ms) COMMIT => #<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 use it.
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> irb(main):002:0> p.id => nil
Doing that, you can see the person didn't get the id. Why did this happen?
Right now, if we try to pass a uuid to our object, it should work.
irb(main):002:0> p.id => nil irb(main):003:0> p.id = SecureRandom.uuid => "e3e0f7c2-8a85-42b9-a31d-867504cb6eb5" irb(main):004:0> p.id => "e3e0f7c2-8a85-42b9-a31d-867504cb6eb5"
I hope this post helps you see how simple it is to use uuids in Rails.