Миграции ActiveRecord с первичным ключом UUID - PullRequest
6 голосов
/ 14 февраля 2011

В миграции, которую я хочу создать, первичным ключом таблицы является поле с именем "id", но оно не является целым числом с автоинкрементом. Тип данных должен быть уникальным идентификатором (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

Это создает таблицу в порядке, но нет первичного ключа (потому что я сказал: id => false). Если бы я сказал «create_table: some_things,: id => true,: primary =>: id», то «id» становится первичным ключом, но это целое число с автоинкрементом, а не uuid без автоинкремента. 1004 *

Как я могу заставить эту миграцию работать так, чтобы первичный ключ представлял собой поле с именем "id" типа "uniqueidentifier" (без автоинкрементации)?

Я использую: SQL Server 2008, Rails / ActiveRecord 3.0.3, камень activerecord-sqlserver-adapter, и соединение ODBC.

Ответы [ 2 ]

1 голос
/ 05 апреля 2013

Вот как я решил эту проблему:

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 ... но я публикую это, потому что это кажется относящимся к одной из ваших проблем, а именно, как вы используете Rails, чтобы держать БД на расстоянии вытянутой руки? Во всяком случае, UUIDtools не зависит от БД.

4) В моем классе Thing я использую это

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

Но мое решение немного отличается.

1 голос
/ 24 мая 2012

Я не знаю, как решить проблему напрямую, но у меня есть обходной путь.

Вставьте идентификатор столбца миграции без директивы «primary». И после того, как метод 'create_table' в миграции выполнит ограничение добавления SQL

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

(не используйте MSSQL и может быть ошибкой в ​​синтаксисе SQL для него)

В вашей модели определите первичный ключ, добавив

self.primary_key = "id"

или

set_primary_key :id
...