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
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
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.
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
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:
serial8
as id type, which is 64 bit integer, and define it as primary key
.timestamptz
as datetime type, which contain the timezone info, this is important for a application that go across multiple timezones.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.)