【问题标题】:Rails 5: How can I change an existing model's ID type to UUID?Rails 5:如何将现有模型的 ID 类型更改为 UUID?
【发布时间】:2018-09-09 21:23:08
【问题描述】:

我正在尝试将 Devise User 模型的 id 类型更改为 uuid。

我的迁移如下所示:

class ChangeUserIdTypeToUuid < ActiveRecord::Migration[5.2]

  def up
    change_column :users, :id, :uuid
  end

  def down
    change_column :users, :id, :integer
  end
end

但是当我运行迁移时出现错误:

== 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

那里有一个提示,但我不知道它在暗示我做什么。不是这个:

change_column :users, :id, id::uuid

为什么迁移失败?提示是什么意思?如何将 ID 类型更改为 UUID?

【问题讨论】:

  • 好吧,也许我弄错了,但你不能像那样将 ID 转换为 UUID。 UUID 是“非常独特”的标识符,而 ActiveRecord 的 ID 只是自然数,所以首先您必须定义一个将常规 ID 转换为 UUID 的策略(即将 1 转换为 123e4567-e89b-12d3-a456-426655440000 之类的东西)。然后,您还必须记住将此 ID 的更改传播到引用您的用户 ID 的所有其他表(如果您在用户模型上有任何关系)

标签: ruby-on-rails


【解决方案1】:

参考post,这被建议重复,我已经设法将id 类型更改为uuid,如下所示:

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

与链接问题中最佳答案的区别在于 UUID 的生成方式。我使用 postgresql 作为我的开发数据库,​​所以我使用的是 gen_random_uuid(),它是由 pgcrypto 扩展提供的,我之前启用该扩展以准备在另一个模型中使用 UUID:

class EnablePgcryptoExtension < ActiveRecord::Migration[5.2]
  def change
    enable_extension 'pgcrypto'
  end
end

【讨论】:

  • 我不确定反向过程迁移(将 uuid 转换为整数)是否有效,因此您可能希望使迁移不可逆。您可以通过在下块中提高 ActiveRecord::IrreversibleMigration 来做到这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-27
  • 2016-11-25
  • 2019-08-06
  • 2013-12-19
  • 2023-02-08
  • 1970-01-01
相关资源
最近更新 更多