How to use long id in Rails applications?

后端 未结 11 1521
天涯浪人
天涯浪人 2020-11-30 22:24

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 on

相关标签:
11条回答
  • 2020-11-30 22:55

    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:

    gem 'activerecord-native_db_types_override'
    

    then in config/environment.rb, to use long ids in postgres, add:

    NativeDbTypesOverride.configure({
      postgres: {
        primary_key: { name: "bigserial primary key"}
      }
    })
    

    See its README for up-to-date info.

    0 讨论(0)
  • 2020-11-30 22:56

    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:

    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").

    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.

    0 讨论(0)
  • 2020-11-30 22:58

    Credits to 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 => false which disables the automatic creation of the id field
    • The t.integer :id, :limit => 8 line will produce a 64 bit integer field
    0 讨论(0)
  • 2020-11-30 22:59

    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:

        create_table :notification_logs, :id => false do |t|
    
          t.column :id, :long_primary_key
          # ...
        end
    
    0 讨论(0)
  • 2020-11-30 23:00

    If anyone needs this to work with PostgreSQL, create an initializer like this:

    # 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::PostgreSQLAdapter won't be required until you establish the database connection.

    0 讨论(0)
  • 2020-11-30 23:00

    Correction to how to change the default primary key column type:

    Instead of:

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

    you should do:

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

    or else you won't be able to add foreign key restrictions in the database layer.

    0 讨论(0)
提交回复
热议问题