ActiveRecord Migrations with UUID Primary Key

In the migration I want to create, the main key of the table is a field called "id", but it is not an automatically increasing integer. This data type must be uniqueidentifier (uuid). Here is what I tried:

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 

This creates the table in order, but there is no primary key (because I said: id => false). If I said "create_table: some_things ,: id => true ,: primary =>: id", then "id" becomes the primary key, but it is an automatically increasing integer, not a non-invasively incremental uuid.

How can I perform this migration so that the primary key is an "id" field of type "uniqueidentifier" (non-automatic increment)?

I use: SQL Server 2008, Rails / ActiveRecord 3.0.3, the pearl of the activerecord-sqlserver adapter, and the ODBC connection.

+6
sql-server ruby-on-rails-3 primary-key rails-migrations
source share
2 answers

I do not know how to solve the problem directly, but I have a workaround.

Insert the id of the migration column without the 'primary' directive. And after the create_table method in the migration executes SQL add constraint

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

(do not use MSSQL and may be a mistake in the SQL syntax for it)

In your model, specify the primary key by adding

 self.primary_key = "id" 

or

 set_primary_key :id 
+1
source share

Here is how I solved this problem:

1) In my migration, I allowed the switch to id and id_sequence auto-generation and added a dummy uuid column (called guid here). It was simply the easiest way to go on a development path. So for

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

I use migration

 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) After migration, I can run the following through sql client

 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) I use two gems to help with this

 gem 'uuidtools' gem 'postgres_ext' 

It is clear that my solution contradicts the Postgres database ... but I am posting it because it seems like one of your problems, namely, how do you use Rails to keep db at arm's length? Anyway, UUIDtools db is agnostic.

4) In my thing class I use this

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

where UUID is just such a module

 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 

By the way, I found the latter in this meaning:

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

But my decision is a little different.

+1
source share

All Articles