'Rails + Postgres migration - why am I receiving the error "PG::UndefinedFunction: ERROR: function gen_random_uuid() does not exist"?

One of my Rails migrations uses a uuid as the primary key. The Postgres extension gen_random_uuid() should solve this issue, but I continue to get the error after installing the relevant extension (uuid-ossp).



Solution 1:[1]

The issue was that the uuid-ossp extension was being blown away with the database each time I dropped the db as part of a reset and migration (e.g. rake db:drop db:create db:migrate).

The fix is to create a migration that's run before all other migrations which enables the relevant extension(s). Like so (db/migrate/0_enable_extensions.rb):

class EnableExtensions < ActiveRecord::Migration[5.1]
  def change
    enable_extension 'uuid-ossp'
    enable_extension 'pgcrypto'
  end
end

Solution 2:[2]

Edge case answer:

Add the migration enabling the extension as stated above.

If you've previously had bigint id's and you're converting over to UUID, running rake db:reset db:migrate failed for me. Be sure to run rake db:drop db:create db:migrate as stated above!

If you get the error Environment data not found in the schema, run bin/rails db:environment:set RAILS_ENV=development.

Solution 3:[3]

I got the same error after generating a model with uuid as primary key like this:

rails g scaffold user name --primary-key-type=uuid

I'd forgotten to load the pgcrypto extension in the migration file.

Solution:

Just add this

enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')

to the migration file like so:

class CreateUsers < ActiveRecord::Migration[7.0]
  enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto') # <-- HERE
  def change
    create_table :users, id: :uuid do |t|
      t.string :name
      t.timestamps
    end
  end
end

Then rake db:migrate will succeed.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user3006381
Solution 2 Stone
Solution 3 stevec