如何在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) unsigned
, person_id
是int(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
,你可以做到这一点。
以下是在rails4
和postgres
创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
作为datetimestamptz
types,其中包含时区信息,这对跨越多个时区的应用程序非常重要。
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
限制。