如何在Rails应用程序中使用long id?

Bjö*_*örn 38 int activerecord ruby-on-rails bigint long-integer

如何更改ActiveRecord ID的(默认)类型?int不够长,我宁愿长.令我感到惊讶的是,没有:迁移很久 - 是否只使用一些小数?

Not*_*ist 49

积分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
Run Code Online (Sandbox Code Playgroud)
  • 请参阅:id => false禁用自动创建id字段的选项
  • t.integer :id, :limit => 8行将产生64位整数字段

  • 不幸的是,这不会将id列创建为主键等. (10认同)

cho*_*eat 43

要设置默认主键列类型,迁移文件不是可以搞乱的地方.

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

ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
Run Code Online (Sandbox Code Playgroud)

并且应使用预期的列类型创建所有表id:

+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| id           | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment | 
Run Code Online (Sandbox Code Playgroud)

在你完成了你要做的事情之后......下一个问题可能是"我如何使我的外键列具有相同的列类型?" 因为它没有任何意义有主键people.idbigint(20) unsigned,而且person_idint(11)还是别的什么吗?

对于这些列,您可以参考其他建议,例如

t.column :author_id, 'BIGINT UNSIGNED'
t.integer :author_id, :limit => 8
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

  • 至少在Rails 2.3.x中,我会非常推荐使用create-then-change.如果在运行此迁移后检查db/schema.rb文件,您会发现它没有提及您的更改,因此任何从架构(如测试)创建数据库的人都不会具有相同的结构. (2认同)

Luk*_*ncl 7

这很难为迁移的主键设置,因为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
Run Code Online (Sandbox Code Playgroud)

如果我有"bigint",您可以将数据库用于您要使用的数据库列类型的任何文本(例如,"unsigned long").

如果您需要将id列作为bigint,最简单的方法是创建表,然后使用change_column更改同一迁移中的列.

使用PostgreSQL和SQLite,架构更改是原子的,因此如果迁移失败,这将不会使您的数据库处于奇怪的状态.使用MySQL,您需要更加小心.


Yeh*_*atz 6

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

:string
:text
:integer
:float
:decimal
:datetime
:timestamp
:time
:date
:binary
:boolean
Run Code Online (Sandbox Code Playgroud)

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

class MyMigration
  def self.up
    execute "ALTER TABLE my_table ADD id LONG"
  end
end
Run Code Online (Sandbox Code Playgroud)

正如wappos指出的那样,您可以使用辅助选项,例如:limit来告诉ActiveRecord您希望列的大小.因此,您将使用带有更大:limit的:int列.

  • 我只是在Rails文档中查找它,如果在整数列上使用:limit => 8,您将得到一个bigint.我没有意识到这一点. (2认同)

Bra*_*dan 5

如果有人需要这个来使用PostgreSQL,请创建一个这样的初始化器:

# config/initializers/bigint_primary_keys.rb
ActiveRecord::Base.establish_connection
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = 'bigserial primary key'
Run Code Online (Sandbox Code Playgroud)

由于Rails 3.2(甚至更早版本)中的延迟加载,在ActiveRecord::ConnectionAdapters::PostgreSQLAdapter建立数据库连接之前不需要.