38 votes

Comment utiliser l'identifiant long dans les applications Rails?

Comment modifier 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 longue attente pour les migrations - utilise-t-on simplement des décimales?

49voto

Notinlist Points 3060

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
 
  • Voir l’option :id => false qui désactive la création automatique du champ id
  • La ligne t.integer :id, :limit => 8 produira un champ entier de 64 bits

43voto

choonkeat Points 4457

Pour définir la valeur par défaut de la clé primaire de la colonne type, les fichiers de migration ne sont pas le lieu pour salir.

Au lieu de cela, il suffit de coller ce 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 pour id:

+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| id           | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment | 

Après que vous avez fait ce que vous avez prévu de le faire... la prochaine question est sans doute: "Comment dois-je faire de mes colonnes de clé étrangère le même type de colonne?" car il ne fait pas de sens d'avoir de la clé primaire people.id comme bigint(20) unsigned, et person_id être int(11) ou autre chose?

Pour les colonnes, vous pouvez vous référer à d'autres suggestions, par exemple

t.column :author_id, 'BIGINT UNSIGNED'
t.integer :author_id, :limit => 8

Mise à JOUR: @Notinlist, à l'utilisation arbitraire de la colonne de clé primaire arbitraire et les tables dont vous avez besoin pour faire de l' create_table-change_column danse:

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 de l'auto-incrément entiers,

create_table(:users, :primary_key => 'guid') do |t|
  # column definitions here..
end
change_column :users, :guid, :string, :limit => 36

7voto

Luke Francl Points 11707

Il est difficile de définir la clé primaire avec les migrations, car les Rails, il met automatiquement.

Vous pouvez modifier n'importe quelle colonne, plus tard, comme ceci:

change_column :foobars, :something_id, 'bigint'

Vous pouvez spécifier non primaire Id comme des types personnalisés dans votre migration initiale comme ceci:

create_table :tweets do |t|
  t.column :twitter_id, 'bigint'
  t.column :twitter_in_reply_to_status_id, 'bigint'
end

Où j'ai "bigint" vous pouvez mettre n'importe quel texte de votre base de données à utiliser pour la base de données de type de colonne que vous souhaitez utiliser (par exemple, "unsigned long").

Si vous avez besoin de votre id de colonne à un bigint, la meilleure façon de le faire serait de créer la table, puis modifier la colonne de la même migration avec change_column.

Avec PostgreSQL et SQLite, les modifications de schéma sont atomiques et donc, cela ne laissera pas votre base de données dans un drôle d'état en cas d'échec de la migration. Avec MySQL, vous devez être plus prudent.

6voto

Yehuda Katz Points 18277

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.

5voto

Brandan Points 8311

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X