2011-02-14 118 views
6

在我想要创建的迁移中,表的主键是一个名为“id”的字段,但它不是自动递增整数。它的数据类型应该是uniqueidentifier(一个uuid)。这是我曾尝试过的:使用UUID主键的ActiveRecord迁移

create_table :some_things, :id => false do |t| 
    t.column :id, :uniqueidentifier, :primary => true 
    t.column :name, :string, :limit => 255 
    t.column :type, :tinyint 
    t.column :deleted_flag, :bit 
    t.column :class_id, :uniqueidentifier 
    t.timestamps 
end 

这创建了表,但没有主键(因为我说:id => false)。如果我说“create_table:some_things,:id => true,:primary =>:id”,那么“id”就成为主键,但它是一个自动递增的整数,而不是非自动递增的uuid。

如何使此迁移工作,以便主键是一个称为“id”类型“uniqueidentifier”(非自动递增)的字段?

我使用: SQL Server 2008中, 的Rails/ActiveRecord的3.0.3, ActiveRecord的 - SQLSERVER适配器宝石, 和ODBC连接。

+0

这是http://stackoverflow.com/questions/1200568/using-rails-how-can-i-set-my-primary-key-to-not-be-an-integer-typed-专栏 - 我们应该整理这些问题吗? – 2013-03-05 02:06:07

回答

1

我不知道如何直接解决问题,但我有一个解决方法。

在没有“主要”指令的情况下输入您的迁移列ID。和方法后,“CREATE_TABLE”迁移执行SQL的附加约束

execute "ALTER TABLE some_things ADD PRIMARY KEY (id);" 

(不使用MSSQL,并且可以在SQL语法为它的错误)加入

在模型中定义主键

self.primary_key = "id" 

set_primary_key :id 
1

这里是我是如何解决这个问题:

1)在我的迁移中,我允许迁移自动生成id和id_sequence,并添加了一个虚拟uuid列(在此称为guid)。这只是走向发展道路的最简单的方式。因此,对于

class Thing < ActiveRecord::Base 
    attr_accessible :name, :description, :guid 
end 

我用迁移

class CreateThings < ActiveRecord::Migration 
    def change 
    create_table :things do |t| 
     t.string :name 
     t.string :description 
     t.uuid :guid 

     t.timestamps 
    end 
    end 
end 

2)迁移后,我可以运行通过SQL客户端

ALTER TABLE things DROP CONSTRAINT things_pkey; 
ALTER TABLE things ADD PRIMARY KEY (guid); 
ALTER TABLE things DROP COLUMN id; 
ALTER TABLE things RENAME COLUMN guid TO id; 

3)我使用的两种宝石帮助下与此

gem 'uuidtools' 
gem 'postgres_ext' 

显然,我的解决方案是针对Postgres DB的......但是我发布这个是因为它看起来与你的一个问题有关,也就是说你如何使用Rails来保持db的长度?无论如何,UUIDtools是不可知的。

4)我的事类我用这个

class Thing < ActiveRecord::Base 
    include Extensions::UUID 

其中UUID是简单的,像这样

module Extensions 
    module UUID 
    extend ActiveSupport::Concern 

    included do 
     # set_primary_key 'guid' 
     before_create :generate_uuid 

     def generate_uuid 
     self.id = UUIDTools::UUID.random_create.to_s 
     end 
    end 
    end 
end 

顺便说一个模块,我发现后者在这个要点:

https://gist.github.com/rmoriz/937739

但我的解决方案有点不同。