2013-10-25 83 views
0

我使用轨道3.1和红宝石1.9.3,现在我想在轨道3 所以我不喜欢使用UUID概念: -迁移PostgreSQL数据库在UUID轨3.1

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 

这是工作的新数据,现在我想迁移现有的数据与relation.for uuid他们正在使用数据类型作为字符串,在postgresql用于primary_key和外键的数据类型是整数,所以如果我想改变外键整数字符串它是投掷错误。

你能告诉我一些例子,如何做到这一点。

kingston.s

回答

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,其方式与正常生成增量型整数ID相同。当你想一个UUID字段添加到现有表:

change_table :posts do |t| 
    t.uuid :uuid, default: 'uuid_generate_v4()' 
end 

默认:“uuid_generate_v4()”将确保新的UUID是由Postgres为您生成。第三,要实际迁移现有数据,我想您需要创建迁移: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”,但我不知道如何做到这一点从我的头顶。无论如何,我认为这种方法应该可行。虽然可能有一些错误或缺失,但在这里稍晚。

+1

这对Rails 3中的我不起作用,但它看起来与其他人在Rails 4中做的类似。您确定这适用于Rails 3吗? – alalani

+0

我有同样的问题,尤其是'default:'uuid_generate_v4()'对我造成了问题,因为它是以字符串形式输入create语句的。 如果你遇到这个rails 3特定的问题,我鼓励在create table语句中调用'to_sql'并使用它来修改CREATE TABLE语句(例如,对函数进行解析)。 – quetzaluz