'Rails 5: How can I change an existing model's ID type to UUID?
I'm trying to change a Devise User model's id type to a uuid.
My migration looks like this:
class ChangeUserIdTypeToUuid < ActiveRecord::Migration[5.2]
def up
change_column :users, :id, :uuid
end
def down
change_column :users, :id, :integer
end
end
But when I run the migration I get an error:
== 20180909205634 ChangeUserIdTypeToUuid: migrating ===========================
-- change_column(:users, :id, :uuid)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::DatatypeMismatch: ERROR: column "id" cannot be cast automatically to type uuid
HINT: You might need to specify "USING id::uuid".
: ALTER TABLE "users" ALTER COLUMN "id" TYPE uuid
There's a hint in there but I don't know what it's suggesting I do. It's not this:
change_column :users, :id, id::uuid
Why is the migration failing? What is the hint suggesting? How do I change the ID type to UUID?
Solution 1:[1]
Referring to the post this was suggested to be a duplicate of, I have managed to change the id
type to uuid
like so:
class ChangeUserIdTypeToUuid < ActiveRecord::Migration[5.2]
def change
add_column :users, :uuid, :uuid, default: "gen_random_uuid()", null: false
change_table :users do |t|
t.remove :id
t.rename :uuid, :id
end
execute "ALTER TABLE users ADD PRIMARY KEY (id);"
end
end
The difference from the best answer in the linked question is the way the UUID is generated. I'm using postgresql as my development db so I'm using gen_random_uuid()
which is provided by the pgcrypto
extension which I had previously enabled in preparation of using UUIDs in another model:
class EnablePgcryptoExtension < ActiveRecord::Migration[5.2]
def change
enable_extension 'pgcrypto'
end
end
Solution 2:[2]
In my case, I wanted to change the type of existing uuid fields from string to uuid, after having enabled the pgcrypto extension already. I had to specify a using:
parameter like so:
def up
change_column :my_table, :uuid_field_name, :uuid, using: "uuid::uuid"
end
def down
change_column :my_table, :uuid_field_name, :string
end
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 | user3574603 |
Solution 2 | pierrea |