我正在使用rails 3.1和ruby 1.9.3,现在我想在rails 3中使用uuid概念 所以我喜欢: -
create_table :posts, :id => false do |t|
t.string :uuid, :limit => 36, :primary => true
end
ActiveRecord::Base.class_eval do
set_primary_key 'uuid'
before_create :generate_uuid
def generate_uuid
self.id = UUIDTools::UUID.random_create.to_s
end
end
这适用于新数据,现在我想用关系迁移现有数据。因为uuid他们使用数据类型作为字符串,在postgresql中用于primary_key和外键的数据类型是整数,所以如果我想改变字符串的外键整数是抛出错误。
请你告诉我一些例子,如何做到这一点。
kingston.s
答案 0 :(得分:2)
首先,要在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,其方式与通常生成增量Integer 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”,但我不知道如何做到这一点。无论如何,我认为这种方法应该有效。可能会有一些错误或缺失,但这里有点晚了。