Introduction
Rails 5.1 brings many improvements and plenty of changes. Among them is the change of function that is used when generating UUIDs.
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:
$ rails generate migration enable_pgcrypto_extensionThen change the file to enable the extension. It should look something like this:
class EnablePgcryptoExtension < ActiveRecord::Migration[5.1]
def change
enable_extension 'pgcrypto'
end
endChange the primary default type
When you generate models ActiveRecord will use Integer as the type for id by default. In Rails 5 you can change this behaviour by adding the following to your config/application.rb file.
config.generators do |g|
g.orm :active_record, primary_key_type: :uuid
endTry it out
Now when you run rails generate model post title:string your migration file should look something like this:
class CreatePosts < ActiveRecord::Migration[5.1]
def change
create_table :posts, id: :uuid do |t|
t.string :title
t.timestamps
end
end
endFurther help
It’s most likely you’ve ended up here from a Google search, here are some errors that you might experience that relate to this guide:
I get an error about gen_random_uuid when I run rake db:migrate ?
If you get the following error when you run rake db:migrate then it’s likely you’ve hit the issue I wrote this post above.
function gen_random_uuid() does not existI get an error about uuid_generate_v4 when I run rake db:migrate ?
If you get the following error when you run rake db:migrate:
function uuid_generate_v4() does not existIt’s likely you have old references to uuid_generate_v4 in your code. Most likely a migration like this:
add_column :posts, :id, default: "uuid_generate_v4()", null: falseTo ensure all your old as well as your new migrations continue to run simply enable both extensions in a migration:
class EnablePgcryptoExtension < ActiveRecord::Migration[5.1]
def change
enable_extension 'uuid-ossp'
enable_extension 'pgcrypto'
end
end