使用rails 5.1.beta1mysql2,迁移应使用defaultBIGINT作为主键整数。

我的主键仍然都是4位整数。



例:

db / migrate / 20170311112129_create_receipts.rb

class CreateReceipts < ActiveRecord::Migration[5.1]
  def change
    create_table :receipts do |t|

      t.timestamps null: false
    end
  end
end


尝试将BIGINT之类的5473508900871246157设置为id时,Rails引发以下异常:


  ActiveModel :: RangeError:5473508900871246157超出了ActiveModel :: Type :: Integer的范围,限制为4个字节

最佳答案

在Rails 5.1.beta1中,主键仍然是4个字节的整数,因为它不能在master上再现。但是,如果要设置BigInt即8字节无符号值,则可以尝试以下方法:

情况1:如果您尚未迁移或表中没有数据。对于特定的表,您可以使用:

class CreateReceipts < ActiveRecord::Migration[5.1]
  def change
    create_table :receipts, :id => false do |t|
      t.integer :id, :limit => 8
      t.timestamps null: false
    end
  end
end


情况2:您已经迁移,不想丢失数据。
在这种情况下,您可以添加新的迁移。

rails g migration change_primary_key_to_bigint_on_receipts


并在生成的迁移文件中添加

def change
  change_column :receipts, :id, :bigint
end


我已经在Rails 5.0.2和5.1.beta1中尝试了这种方法,并且在两个版本中都可以正常工作。

情况3:您想为创建的每个表将默认主键设置为BigInt,并且不想弄乱迁移文件。
将此添加到config/environment.rb的底部

ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"


除情况2外,您还可以使用execute方法更改ID类型

def up
  execute('ALTER TABLE receipts MODIFY COLUMN id BIGINT(8) NOT NULL AUTO_INCREMENT')
end

def down
  raise ActiveRecord::IrreversibleMigration
end


ActiveRecord不支持此功能。此方法的缺点是,当您回滚迁移时,ActiveRecord会引发错误,因为它不知道如何还原它。

07-25 21:50
查看更多