How to use long id in Rails applications?

后端 未结 11 1523
天涯浪人
天涯浪人 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 23:06

    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

    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:

    +--------------+---------------------+------+-----+---------+----------------+
    | 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.id as bigint(20) unsigned, and person_id be int(11) or anything else?

    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_column dance:

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

    e.g. if I wanted guid instead of auto-increment integers,

    create_table(:users, :primary_key => 'guid') do |t|
      # column definitions here..
    end
    change_column :users, :guid, :string, :limit => 36
    
    0 讨论(0)
  • 2020-11-30 23:08

    According to the Rails API documentation, the possible options for type are:

    :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:

    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.

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

    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
    
    0 讨论(0)
  • 2020-11-30 23:18

    In rails4, you can do it.

    Following is an example to create a Dummy model in rails4 & postgres,

    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 serial8 as id type, which is 64 bit integer, and define it as primary key.
    • It use timestamptz as datetime type, which contain the timezone info, this is important for a application that go across multiple timezones.
    0 讨论(0)
  • 2020-11-30 23:19

    Rails 3, MySQL:

    t.column :foobar, :int, :limit => 8
    

    Does not give me a bigint, only an int. However,

    t.column :twitter_id, 'bigint'
    

    works fine. (Although it does tie me to MySQL.)

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