Ruby-on-rails 如何在 Rails 应用程序中使用长 ID?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1066340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use long id in Rails applications?
提问by Bj?rn
How can I change the (default) type for ActiveRecord's IDs? int is not long enough, I would prefer long. I was surprised that there is no :long for the migrations - does one just use some decimal?
如何更改 ActiveRecord 的 ID 的(默认)类型?int 不够长,我宁愿长。我很惊讶没有 :long 迁移 - 是否只使用一些小数?
回答by Notinlist
Credits to http://moeffju.net/blog/using-bigint-columns-in-rails-migrations
归功于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
- See the option
:id => falsewhich disables the automatic creation of the id field - The
t.integer :id, :limit => 8line will produce a 64 bit integer field
- 查看
:id => false禁用自动创建 id 字段的选项 - 该
t.integer :id, :limit => 8行将产生一个 64 位整数字段
回答by choonkeat
To set the default primary key column type, the migration files are not the place to mess with.
要设置默认的主键列类型,迁移文件不是乱七八糟的地方。
Instead, just stick this at the bottom of your config/environment.rb
相反,只需将其粘贴在您的底部 config/environment.rb
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
And all your tables should be created with the intended column type for id:
并且您的所有表都应使用预期的列类型创建id:
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
After you've done what you've set out to do... the next question is probably "How do I make my foreign key columns the same column type?" since it does not make sense to have primary key people.idas bigint(20) unsigned, and person_idbe int(11)or anything else?
在您完成您打算做的事情之后……下一个问题可能是“如何使我的外键列具有相同的列类型?” 因为将主键people.id作为bigint(20) unsigned、 和person_id是int(11)或其他任何东西是没有意义的?
For those columns, you can refer to the other suggestions, e.g.
对于这些列,您可以参考其他建议,例如
t.column :author_id, 'BIGINT UNSIGNED'
t.integer :author_id, :limit => 8
UPDATE: @Notinlist, to use arbitrary column for primary key on arbitrary tables you need to do the create_table-change_columndance:
更新:@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. if I wanted guidinstead of auto-increment integers,
例如,如果我想要guid而不是自动递增整数,
create_table(:users, :primary_key => 'guid') do |t|
# column definitions here..
end
change_column :users, :guid, :string, :limit => 36
回答by Luke Francl
This is hard to set for the primary key with migrations because Rails puts it in automatically.
这很难为带有迁移的主键设置,因为 Rails 会自动将其放入。
You can change any column later like this:
您可以稍后像这样更改任何列:
change_column :foobars, :something_id, 'bigint'
change_column :foobars, :something_id, 'bigint'
You can specify non-primary IDs as custom types in your initial migration like this:
您可以在初始迁移中将非主要 ID 指定为自定义类型,如下所示:
create_table :tweets do |t|
t.column :twitter_id, 'bigint'
t.column :twitter_in_reply_to_status_id, 'bigint'
end
Where I have "bigint" you can put any text that your database would use for the database column type you want to use (e.g., "unsigned long").
在我有“bigint”的地方,您可以放置数据库将用于要使用的数据库列类型的任何文本(例如,“unsigned long”)。
If you need your id column to be a bigint, the easiest way to do it would be to create the table, then change the column in the same migration with change_column.
如果您需要将 id 列设为 bigint,最简单的方法是创建表,然后使用 change_column 在同一迁移中更改列。
With PostgreSQL and SQLite, schema changes are atomic so this won't leave your database in a weird state if the migration fails. With MySQL you need to be more careful.
使用 PostgreSQL 和 SQLite,模式更改是原子性的,因此如果迁移失败,这不会使您的数据库处于奇怪的状态。使用 MySQL,您需要更加小心。
回答by Yehuda Katz
According to the Rails API documentation, the possible options for type are:
根据 Rails API 文档,类型的可能选项是:
:string
:text
:integer
:float
:decimal
:datetime
:timestamp
:time
:date
:binary
:boolean
You can use :decimal, or you can execute a command directly if you need to:
您可以使用 :decimal,或者如果需要,您可以直接执行命令:
class MyMigration
def self.up
execute "ALTER TABLE my_table ADD id LONG"
end
end
As wappos pointed out, you can use auxiliary options like :limit to tell ActiveRecord how large you want the column to be. So you would use the :int column with a larger :limit.
正如 wappos 所指出的,您可以使用诸如 :limit 之类的辅助选项来告诉 ActiveRecord 您希望该列有多大。因此,您将使用具有更大 :limit 的 :int 列。
回答by Brandan
If anyone needs this to work with PostgreSQL, create an initializer like this:
如果有人需要它与 PostgreSQL 一起工作,请创建一个这样的初始化程序:
# config/initializers/bigint_primary_keys.rb
ActiveRecord::Base.establish_connection
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = 'bigserial primary key'
Because of lazy loading in Rails 3.2 (and maybe even earlier versions), ActiveRecord::ConnectionAdapters::PostgreSQLAdapterwon't be required until you establish the database connection.
由于 Rails 3.2(甚至可能更早的版本)中的延迟加载,在ActiveRecord::ConnectionAdapters::PostgreSQLAdapter您建立数据库连接之前不需要。
回答by Eric Wang
In rails4, you can do it.
在rails4,你可以做到。
Following is an example to create a Dummymodel in rails4& postgres,
以下是Dummy在rails4& 中创建模型的示例postgres,
xxx_migrate_dummies.rb:
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
What it did:
它做了什么:
- It use
serial8as id type, which is 64 bit integer, and define it asprimary key. - It use
timestamptzas datetime type, which contain the timezone info, this is important for a application that go across multiple timezones.
- 它
serial8用作 id 类型,它是 64 位整数,并将其定义为primary key. - 它
timestamptz用作日期时间类型,其中包含时区信息,这对于跨越多个时区的应用程序很重要。
回答by z5h
Borrowing from other solutions, adjusted for what worked for me recently.
借鉴其他解决方案,根据最近对我有用的方法进行调整。
Add to a file in config/initializers. It declares a new column type (adapted from chookeat's suggestion).
添加到config/initializers. 它声明了一个新的列类型(改编自 chookeat 的建议)。
ActiveRecord::ConnectionAdapters::Mysql2Adapter::NATIVE_DATABASE_TYPES[:long_primary_key] = "BIGINT(20) DEFAULT NULL auto_increment PRIMARY KEY"
ActiveRecord::ConnectionAdapters::Mysql2Adapter::NATIVE_DATABASE_TYPES[:long_primary_key] = "BIGINT(20) DEFAULT NULL auto_increment PRIMARY KEY"
Migrations that use a long id are as such:
使用长 ID 的迁移如下:
create_table :notification_logs, :id => false do |t|
t.column :id, :long_primary_key
# ...
end
回答by Duke
Rails 3, MySQL:
Rails 3,MySQL:
t.column :foobar, :int, :limit => 8
Does not give me a bigint, only an int. However,
不给我一个 bigint,只有一个 int。然而,
t.column :twitter_id, 'bigint'
works fine. (Although it does tie me to MySQL.)
工作正常。(尽管它确实将我与 MySQL 联系在一起。)
回答by Gary S. Weaver
I wrote a gem called activerecord-native_db_types_overridethat lets you alter the datatypes that will be used in your migrations.
我编写了一个名为activerecord-native_db_types_override的 gem ,它允许您更改将在迁移中使用的数据类型。
In your Gemfile, add:
在您的 Gemfile 中,添加:
gem 'activerecord-native_db_types_override'
then in config/environment.rb, to use long ids in postgres, add:
然后在 config/environment.rb 中,要在 postgres 中使用长 ID,请添加:
NativeDbTypesOverride.configure({
postgres: {
primary_key: { name: "bigserial primary key"}
}
})
See its READMEfor up-to-date info.
有关最新信息,请参阅其自述文件。
回答by Alexander Gorg
You can do it like this:
你可以这样做:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users, id: :bigserial do |t|
t.string :name
end
end
end

