使用UUID作为主键的ActiveRecord迁移

6

在我想创建的迁移中,表的主键是一个名为“id”的字段,但它不是自增整数。 它的数据类型应该是uniqueidentifier(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。
我该如何使迁移工作,以便主键是名为“id”的字段,类型为“uniqueidentifier”(非自增)?
我使用的是: SQL Server 2008, Rails / ActiveRecord 3.0.3, activerecord-sqlserver-adapter gem, 和ODBC连接。

这是 https://dev59.com/OnM_5IYBdhLWcg3w2XFg 的副本 - 我们应该合并这些问题吗? - David J.
2个回答

1

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

在迁移列中输入您的id,不要加上“primary”指令。在迁移中执行“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数据库...但我发布这篇文章是因为它似乎与你的一个问题相关,即如何使用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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接