如何在 Rails 应用程序中使用长 id?
如何更改 ActiveRecord ID 的(默认)类型? int 不够长,我更喜欢 long。 我很惊讶迁移没有 :long - 是否只使用一些小数?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
致谢 http://moeffju.net/blog/using-bigint-columns -in-rails-migrations
:id => false
禁止自动创建 id 字段t.integer :id, :limit => 8
行将产生一个64位整数字段Credits to http://moeffju.net/blog/using-bigint-columns-in-rails-migrations
:id => false
which disables the automatic creation of the id fieldt.integer :id, :limit => 8
line will produce a 64 bit integer field要设置默认主键列类型,迁移文件不是一个可以搞乱的地方。
相反,只需将其粘贴在
config/environment.rb
的底部,并且所有表都应使用
id
的预期列类型创建:完成后你已经开始做...下一个问题可能是“如何使我的外键列具有相同的列类型?” 因为主键
people.id
为bigint(20) unsigned
且person_id
为int(11) 是没有意义的)
还是其他什么?对于这些列,您可以参考其他建议,例如
UPDATE:@Notinlist,要在任意表上使用任意列作为主键,您需要执行
create_table-change_column
dance:例如,如果我想要
guid
而不是自动递增整数,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
And all your tables should be created with the intended column type for
id
: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.id
asbigint(20) unsigned
, andperson_id
beint(11)
or anything else?For those columns, you can refer to the other suggestions, e.g.
UPDATE: @Notinlist, to use arbitrary column for primary key on arbitrary tables you need to do the
create_table-change_column
dance:e.g. if I wanted
guid
instead of auto-increment integers,这很难通过迁移来设置主键,因为 Rails 会自动将其放入。
您可以稍后更改任何列,如下所示:
change_column :foobars, :something_id, 'bigint'
您可以在初始迁移中将非主 ID 指定为自定义类型,如下所示:
Where I have "bigint" you可以放置数据库将用于您要使用的数据库列类型的任何文本(例如“unsigned long”)。
如果您需要 id 列为 bigint,最简单的方法是创建表,然后在同一迁移中使用change_column 更改列。
对于 PostgreSQL 和 SQLite,架构更改是原子的,因此如果迁移失败,数据库不会处于奇怪的状态。 使用 MySQL 时你需要更加小心。
This is hard to set for the primary key with migrations because Rails puts it in automatically.
You can change any column later like this:
change_column :foobars, :something_id, 'bigint'
You can specify non-primary IDs as custom types in your initial migration like this:
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").
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.
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.
根据 Rails API 文档,类型的可能选项有:
您可以使用 :decimal,或者如果需要,您可以直接执行命令:
正如 wappos 指出的,您可以使用辅助选项,如 :limit 来告诉 ActiveRecord 有多大你想要的列是。 因此,您可以使用具有更大 :limit 的 :int 列。
According to the Rails API documentation, the possible options for type are:
You can use :decimal, or you can execute a command directly if you need to:
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.
如果有人需要这个来与 PostgreSQL 一起工作,请创建一个如下的初始化程序:
由于 Rails 3.2(甚至可能是更早版本)中的延迟加载,因此不需要
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
直到您建立数据库连接。If anyone needs this to work with PostgreSQL, create an initializer like this:
Because of lazy loading in Rails 3.2 (and maybe even earlier versions),
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
won't be required until you establish the database connection.在rails4中,你可以做到。
以下是在
rails4
中创建Dummy
模型的示例postgres
,xxx_migrate_dummies.rb:
它做了什么:
serial8
作为id类型,它是64位整数,并将其定义为主键
。timestamptz
作为日期时间类型,其中包含时区信息,这对于跨多个时区的应用程序很重要。In
rails4
, you can do it.Following is an example to create a
Dummy
model inrails4
&postgres
,xxx_migrate_dummies.rb:
What it did:
serial8
as id type, which is 64 bit integer, and define it asprimary key
.timestamptz
as datetime type, which contain the timezone info, this is important for a application that go across multiple timezones.Rails 3,MySQL:
没有给我一个bigint,只有一个int。 不过,
效果很好。 (尽管它确实将我与 MySQL 联系在一起。)
Rails 3, MySQL:
Does not give me a bigint, only an int. However,
works fine. (Although it does tie me to MySQL.)
借鉴其他解决方案,根据最近对我有用的方法进行调整。
添加到
config/initializers
中的文件。 它声明了一个新的列类型(改编自 chookeat 的建议)。ActiveRecord::ConnectionAdapters::Mysql2Adapter::NATIVE_DATABASE_TYPES[:long_primary_key] = "BIGINT(20) DEFAULT NULL auto_increment PRIMARY KEY"
使用长 id 的迁移如下:
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).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:
我编写了一个名为 activerecord-native_db_types_override 的 gem,它允许您更改将在迁移中使用的数据类型。
在 Gemfile 中,添加:
然后在 config/environment.rb 中,要在 postgres 中使用长 ID,添加:
请参阅其 自述文件以获取最新信息。
I wrote a gem called activerecord-native_db_types_override that lets you alter the datatypes that will be used in your migrations.
In your Gemfile, add:
then in config/environment.rb, to use long ids in postgres, add:
See its README for up-to-date info.
你可以这样做:
You can do it like this:
更正如何更改默认
主键
列类型:而不是:
您应该这样做:
否则您将无法在数据库层添加
外键
限制。Correction to how to change the default
primary key
column type:Instead of:
you should do:
or else you won't be able to add
foreign key
restrictions in the database layer.