如何在 Rails 应用程序中使用长 id?
-
21-08-2019 - |
题
如何更改 ActiveRecord ID 的(默认)类型?int 不够长,我更喜欢 long。我很惊讶迁移没有 :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
这会禁用 id 字段的自动创建 - 这
t.integer :id, :limit => 8
line 将产生一个 64 位整数字段
其他提示
要设置默认主键列型下,迁移文件不是地方与混乱。
相反,只要坚持这在你config/environment.rb
底部
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
和所有的表应该与预期的列类型id
创建:
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
在你做你的事已经做......下一个问题可能是“如何让我的外键列在同一列类型?”因为它没有任何意义有主键people.id
为bigint(20) unsigned
和person_id
被int(11)
或别的什么吗?
有关这些栏,可以参考其他建议,e.g。
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
e.g。如果我想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作为自定义类型:
create_table :tweets do |t|
t.column :twitter_id, 'bigint'
t.column :twitter_in_reply_to_status_id, 'bigint'
end
我哪里有“BIGINT”你可以把你的数据库会用您要使用(例如,“无符号长”)的数据库列类型的任何文本。
如果你需要你的id列是一个BIGINT,要做到这将是创建表的最简单的方法,然后用change_column相同的迁移更改列。
在PostgreSQL和SQLite,模式更改是原子因此这不会离开你的数据库在一个奇怪的状态,如果迁移失败。用MySQL,你需要更加小心。
根据该滑轨API文档类型可能的选项是:
:string
:text
:integer
:float
:decimal
:datetime
:timestamp
:time
:date
:binary
:boolean
您可以使用:小数,或者您可以直接,如果你需要执行命令:
class MyMigration
def self.up
execute "ALTER TABLE my_table ADD id LONG"
end
end
由于wappos指出的那样,你可以使用辅助选项,如:极限告诉ActiveRecord的你要多大的列是。所以,你可以使用:整数列具有较大:限制
如果有人需要此PostgreSQL的工作,创建这样的初始化:
# 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
将不再需要,直到你建立数据库连接,延迟加载
在 rails4
, , 你能行的。
以下是创建一个的示例 Dummy
模型中 rails4
& postgres
,
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
作为id类型,它是64位整数,并将其定义为primary key
. - 它使用
timestamptz
作为包含时区信息的日期时间类型,这对于跨多个时区的应用程序很重要。
导轨3时,MySQL:
t.column :foobar, :int, :limit => 8
不给我一个BIGINT,只是一个int。然而,
t.column :twitter_id, 'bigint'
工作正常。 (虽然它确实配合我到MySQL。)
从其他的解决方案,调整为最近我什么工作借贷。
...添加到在config/initializers
一个文件。它声明新的一列型(改编自chookeat的建议)。
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 的宝石,可以让你改变将要使用的数据类型在您的迁移。
在您的Gemfile,添加:
gem 'activerecord-native_db_types_override'
然后在配置/ environment.rb中,使用长的IDS在postgres的,添加:
NativeDbTypesOverride.configure({
postgres: {
primary_key: { name: "bigserial primary key"}
}
})
请参阅其自述长达最新信息。
您可以做这样的:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users, id: :bigserial do |t|
t.string :name
end
end
end
校正如何改变默认primary key
柱类型:
代替:
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
限制。