6

En la migración que deseo crear, la clave principal de la tabla es un campo llamado "id" pero no es un entero de incremento automático. Su tipo de datos debe ser uniqueidentifier (uuid). Esto es lo que he intentado:Migraciones de ActiveRecord con clave principal de UUID

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 

Esto crea la tabla bien, pero no hay ninguna clave primaria (porque dije: id => false). Si dije "create_table: some_things,: id => true,: primary =>: id", entonces "id" se convierte en la clave principal, pero es un entero de incremento automático, no un uuid de incremento no automático.

¿Cómo puedo hacer que esta migración funcione para que la clave principal sea un campo llamado "id" de tipo "uniqueidentifier" (no auto-incrementado)?

que estoy usando: SQL Server 2008, rieles/ActiveRecord 3.0.3, la gema activerecord-sqlserver-adaptador, y una conexión ODBC.

+0

Este es un duplicado de http://stackoverflow.com/questions/1200568/using-rails-how-can-i-set-my-primary-key-to-not-be-an-integer-typed- columna - ¿debemos consolidar las preguntas? –

Respuesta

1

No sé cómo resolver el problema directamente, pero tengo una solución.

Coloque su identificación de la columna de migración sin la directiva 'primaria'. Y después de método 'create_table' en la migración ejecutar restricción complemento de SQL

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

(no utilice MSSQL y puede ser error en SQL-sintaxis para ello)

En su modelo definir la clave principal mediante la adición de

self.primary_key = "id" 

o

set_primary_key :id 
1

Aquí fue como resuelto este problema:

1) En mi migración, permití que la migración generara automáticamente el id y la id_sequence, y agregué una columna uuid ficticia (llamada guid aquí). Era simplemente la forma más fácil de ir en la ruta de desarrollo. Así que para

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

utilizo la migración

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) Después de la migración, que se puede ejecutar la siguiente a través de un cliente de 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) estoy usando dos joyas para ayudar con esto

gem 'uuidtools' 
gem 'postgres_ext' 

Claramente, mi solución es contra un DB de Postgres ... pero publico esto porque parece relevante para uno de sus problemas, es decir, ¿cómo usa Rails para mantener el DB a la altura de los brazos? En cualquier caso, UUIDtools es db agnostic.

4) En mi clase de cosa que utilizo este

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

donde UUID es simplemente un módulo igual que

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 

Por cierto, me encontré con este último en este GIST:

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

Pero mi solución es un poco diferente.

Cuestiones relacionadas