首先,要在 ActiveRecord 中使用 UUID,您需要启用 uuid-ossp 扩展。创建一个新的迁移。
class EnableUuidOssp < ActiveRecord::Migration
def change
enable_extension 'uuid-ossp'
end
end
其次,您不需要在迁移中使用字符串类型,有一个 uuid 类型。创建新表时:
create_table :posts, id: :uuid do |t|
end
这将自动生成一个 UUID,其方式与通常生成增量整数 ID 的方式相同。当您想将 UUID 字段添加到现有表时:
change_table :posts do |t|
t.uuid :uuid, default: 'uuid_generate_v4()'
end
默认值:'uuid_generate_v4()' 将确保 Postgres 为您生成一个新的 UUID。
第三,要实际迁移现有数据,我想您需要创建迁移 1)将 UUID 字段添加到所有模型 2)创建新的 UUID 外键 3)使用 UUID 外键关联模型 4)删除旧的外键5)重命名新的外键:
class AddUuidToPosts < ActiveRecord::Migration
def change
change_table :posts do |t|
t.uuid :uuid, default: 'uuid_generate_v4()'
end
end
end
# assuming you have a comments table that belongs to posts
class AddUuidToComments < ActiveRecord::Migration
def change
change_table :comments do |t|
t.uuid :uuid, default: 'uuid_generate_v4()'
end
end
end
class AssociateCommentsWithPostings < ActiveRecord::Migration
def change
# Add a uuid_posting_id field to comments relate comments to postings
# through the posting UUID
change_table :comments do |t|
t.uuid :uuid_posting_id
end
# Loop through all existing postings and update all associated comments
# new foreign key field
Posting.all.each do |posting|
# Not sure about this, but you might need to touch the posting to generate
# a UUID
posting.touch
Comment.where(posting_id: posting.id).
update_all(uuid_posting_id: posting.uuid)
end
remove_column :comments, :posting_id
rename_column :comments, :uuid_posting_id, :posting_id
end
end
# You don't need to override ActiveRecord::Base to set the primary key to :uuid.
# Only do this in existing models that you migrated to UUIDs. In any new tables
# that you create, the id column will be a UUID, as long as you use the migration
# format that I showed you at the top.
class Posting < ActiveRecord::Base
set_primary_key :uuid
end
您可能应该加倍努力,实际上删除旧的整数 id 字段并将新的 UUID id 重命名为“id”,但我不知道该怎么做。无论如何,我认为这种方法应该有效。虽然可能有几个错误或位丢失,但这里有点晚了。