如何在Rails应用程序中使用长ID?

如何更改ActiveRecord的ID的(默认)types? int不够长,我更喜欢long。 我感到惊讶的是,没有:迁移的长期 – 一个只是使用一些小数?

学分http://moeffju.net/blog/using-bigint-columns-in-rails-migrations

class CreateDemo < ActiveRecord::Migration def self.up create_table :demo, :id => false do |t| t.integer :id, :limit => 8 end end end 
  • 请参阅选项:id => false ,禁用自动创buildid字段
  • t.integer :id, :limit => 8行会产生一个64位的整数字段

要设置默认的主键列types ,迁移文件不是混乱的地方。

相反,只需将其粘贴在config/environment.rb的底部即可

 ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY" 

并且所有的表格都应该使用id的目标列types创build:

 +--------------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+---------------------+------+-----+---------+----------------+ | id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | 

当你完成了你所要做的事情之后…下一个问题可能是“我如何让我的外键列是相同的列types? 因为它没有任何意义,有主键people.id作为bigint(20) unsignedperson_idint(11)或其他?

对于这些列,你可以参考其他build议,例如

 t.column :author_id, 'BIGINT UNSIGNED' t.integer :author_id, :limit => 8 

更新 :@Notinlist,在任意表上使用任意列的主键,你需要做的create_table-change_column跳舞:

 create_table(:users) do |t| # column definitions here.. end change_column :users, :id, :float # or some other column type 

例如,如果我想要guid而不是自动增量整数,

 create_table(:users, :primary_key => 'guid') do |t| # column definitions here.. end change_column :users, :guid, :string, :limit => 36 

这是很难设置的主键与迁移,因为Rails自动置入。

您可以稍后更改任何列:

change_column :foobars, :something_id, 'bigint'

您可以在初始迁移中将非主要ID指定为自定义types,如下所示:

 create_table :tweets do |t| t.column :twitter_id, 'bigint' t.column :twitter_in_reply_to_status_id, 'bigint' end 

在我有“bigint”的地方,你可以把你的数据库将要使用的任何文本用于你要使用的数据库列types(例如“unsigned long”)。

如果你需要你的id列是一个bigint,最简单的方法是创build表,然后用change_column改变同一个迁移中的列。

使用PostgreSQL和SQLite,模式更改是primefaces的,所以如果迁移失败,这不会使数据库处于奇怪的状态。 有了MySQL,你需要更加小心。

根据Rails API文档,types的可能选项是:

 :string :text :integer :float :decimal :datetime :timestamp :time :date :binary :boolean 

你可以使用:decimal,或者你可以直接执行命令,如果你需要:

 class MyMigration def self.up execute "ALTER TABLE my_table ADD id LONG" end end 

正如wappos指出的那样,你可以使用如下的辅助选项:limit来告诉ActiveRecord这个列有多大。 所以你可以使用带有更大的:limit的int列。

如果有人需要这个与PostgreSQL一起工作,像这样创build一个初始化程序:

 # config/initializers/bigint_primary_keys.rb ActiveRecord::Base.establish_connection ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = 'bigserial primary key' 

由于在Rails 3.2(甚至更早版本)中的延迟加载, ActiveRecord::ConnectionAdapters::PostgreSQLAdapter将不需要,直到build立数据库连接。

rails4 ,你可以做到这一点。

以下是在rails4postgres创buildDummy模型的rails4

xxx_migrate_dummies.rb:

 class CreateDummies < ActiveRecord::Migration def change create_table :dummies, :id => false do |t| t.column :id, :serial8, primary_key: true t.string :name, :limit => 50, null: false t.integer :size, null: false t.column :create_date, :timestamptz, null: false end end end 

它做了什么:

  • 它使用serial8作为idtypes,这是64位整数,并将其定义primary key
  • 它使用timestamptz作为datetimestamptztypes,其中包含时区信息,这对跨越多个时区的应用程序非常重要。

Rails 3,MySQL:

 t.column :foobar, :int, :limit => 8 

不给我一个bigint,只有一个int。 然而,

 t.column :twitter_id, 'bigint' 

工作正常。 (虽然它使我与MySQL。)

从其他解决scheme借用,最近调整为我工作。

添加到config/initializers的文件。 它声明了一个新的列types(改编自chookeat的build议)。

ActiveRecord::ConnectionAdapters::Mysql2Adapter::NATIVE_DATABASE_TYPES[:long_primary_key] = "BIGINT(20) DEFAULT NULL auto_increment PRIMARY KEY"

使用长ID的迁移是这样的:

  create_table :notification_logs, :id => false do |t| t.column :id, :long_primary_key # ... end 

我写了一个称为activerecord-native_db_types_override的gem,它允许您更改将在您的迁移中使用的数据types。

在您的Gemfile中,添加:

 gem 'activerecord-native_db_types_override' 

然后在config / environment.rb中,在postgres中使用长ID,添加:

 NativeDbTypesOverride.configure({ postgres: { primary_key: { name: "bigserial primary key"} } }) 

查看其README获取最新信息。

你可以这样做:

 class CreateUsers < ActiveRecord::Migration[5.0] def change create_table :users, id: :bigserial do |t| t.string :name end end end 

更正如何更改默认primary key列types:

代替:

 ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY" 

你应该做:

 ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT(8) UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY" 

否则你将无法在数据库层添加foreign key限制。