Comment puis-je changer le type (par défaut) des identifiants d'ActiveRecord? int n'est pas assez long, je préférerais longtemps. J'ai été surpris qu'il n'y ait pas de: long pour les migrations - est-ce qu'on utilise juste une décimale?
Crédits à 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
:id => false
qui désactive la création automatique du champ idt.integer :id, :limit => 8
produira un champ entier de 64 bitsPour définir le type de colonne de clé primaire par défaut , les fichiers de migration ne sont pas l'endroit pour déconner.
Au lieu de cela, collez ceci au bas de votre config/environment.rb
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
Et toutes vos tables doivent être créées avec le type de colonne prévu pour id
:
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
Une fois que vous avez accompli ce que vous aviez prévu de faire, la question suivante est probablement: "Comment puis-je utiliser le même type de colonne pour les colonnes de clé étrangère?" comme il n’a pas de sens d’avoir la clé primaire people.id
comme bigint(20) unsigned
, et person_id
être int(11)
ou quoi que ce soit d'autre?
Pour ces colonnes, vous pouvez vous référer aux autres suggestions, par exemple.
t.column :author_id, 'BIGINT UNSIGNED'
t.integer :author_id, :limit => 8
UPDATE: @Notinlist, pour utiliser une colonne arbitraire pour la clé primaire sur des tables arbitraires, vous devez effectuer la danse create_table-change_column
:
create_table(:users) do |t|
# column definitions here..
end
change_column :users, :id, :float # or some other column type
par exemple. si je voulais guid
au lieu d'entiers auto-incrémentés,
create_table(:users, :primary_key => 'guid') do |t|
# column definitions here..
end
change_column :users, :guid, :string, :limit => 36
Cela est difficile à définir pour la clé primaire avec les migrations car Rails la met automatiquement.
Vous pouvez changer n'importe quelle colonne plus tard comme ceci:
change_column :foobars, :something_id, 'bigint'
Vous pouvez spécifier des ID non principaux en tant que types personnalisés dans votre migration initiale, comme suit:
create_table :tweets do |t|
t.column :Twitter_id, 'bigint'
t.column :Twitter_in_reply_to_status_id, 'bigint'
end
Là où j'ai "bigint", vous pouvez mettre n'importe quel texte que votre base de données utiliserait pour le type de colonne de base de données que vous souhaitez utiliser (par exemple, "unsigned long").
Si vous avez besoin que votre colonne id soit bigint, le moyen le plus simple consiste à créer la table, puis à modifier la colonne dans la même migration avec change_column.
Avec PostgreSQL et SQLite, les modifications de schéma sont atomiques, ce qui ne laissera pas votre base de données dans un état étrange si la migration échoue. Avec MySQL, vous devez être plus prudent.
Selon la documentation de l'API Rails, les options possibles pour le type sont les suivantes:
:string
:text
:integer
:float
:decimal
:datetime
:timestamp
:time
:date
:binary
:boolean
Vous pouvez utiliser: décimal, ou vous pouvez exécuter une commande directement si vous devez:
class MyMigration
def self.up
execute "ALTER TABLE my_table ADD id LONG"
end
end
Comme l'a souligné wappos, vous pouvez utiliser des options auxiliaires telles que: limit pour indiquer à ActiveRecord la taille souhaitée de la colonne. Donc, vous utiliseriez la colonne: int avec une plus grande: limite.
Si quelqu'un a besoin de cela avec PostgreSQL, créez un initialiseur comme ceci:
# config/initializers/bigint_primary_keys.rb
ActiveRecord::Base.establish_connection
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = 'bigserial primary key'
En raison du chargement paresseux dans Rails 3.2 (et peut-être même dans des versions antérieures), ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
ne sera pas nécessaire jusqu'à ce que vous établissiez la connexion à la base de données.
Dans Rails4
, vous pouvez le faire.
Voici un exemple pour créer un modèle Dummy
dans 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
Ce qu'il a fait:
serial8
comme type d'identifiant, qui est un entier de 64 bits, et le définit comme primary key
.timestamptz
comme type date/heure, qui contient les informations de fuseau horaire, ce qui est important pour une application qui utilise plusieurs fuseaux horaires.Rails 3, MySQL:
t.column :foobar, :int, :limit => 8
Ne me donne pas un bigint, seulement un int. cependant,
t.column :Twitter_id, 'bigint'
fonctionne bien. (Bien que cela me lie à MySQL.)
J'ai écrit une perle appelée activerecord-native_db_types_override qui vous permet de modifier les types de données qui seront utilisés dans vos migrations.
Dans votre Gemfile, ajoutez:
gem 'activerecord-native_db_types_override'
puis dans config/environment.rb, pour utiliser des identifiants longs dans postgres, ajoutez:
NativeDbTypesOverride.configure({
postgres: {
primary_key: { name: "bigserial primary key"}
}
})
Voir son README pour des informations à jour.
Vous pouvez le faire comme ça:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users, id: :bigserial do |t|
t.string :name
end
end
end