2011-02-14 93 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

但我的解決方案有點不同。