Question

Comment puis-je changer (par défaut) de type pour les ID de ActiveRecord? int est pas assez long, je préférerais longtemps. J'ai été surpris qu'il n'y a pas: longtemps pour les migrations - on n'utilise que quelques décimales

Était-ce utile?

La solution

Crédits http://moeffju.net/blog/using- bigint-colonnes-en-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 qui désactive la :id => false création automatique du champ id
  • La ligne de t.integer :id, :limit => 8 va produire un champ entier de 64 bits

Autres conseils

Pour régler le par défaut de type colonne de clé primaire , les fichiers de migration ne sont pas l'endroit idéal pour jouer avec.

Au lieu de cela, il suffit de coller ce au fond 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éés avec le type de colonne destiné à id:

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

Une fois que vous avez fait ce que vous avez prévu de faire ... la question suivante est probablement « Comment puis-je faire mes colonnes de clé étrangère le même type de colonne? » car il n'a pas de sens d'avoir la clé primaire comme people.id bigint(20) unsigned, et être person_id ou toute autre chose int(11)?

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, à utiliser la colonne arbitraire clé primaire sur les tables arbitraires que vous devez faire 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 la place des entiers guid auto-incrément,

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

Il est difficile de définir la clé primaire des migrations parce que Rails le met automatiquement.

Vous pouvez modifier plus tard colonne comme ceci:

change_column :foobars, :something_id, 'bigint'

Vous pouvez spécifier les ID non primaires comme 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

Si je « bigint » vous pouvez mettre tout 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 de votre colonne id être un bigint, la meilleure façon de le faire serait de créer la table, puis modifiez la colonne dans la même migration avec change_column.

Avec PostgreSQL et SQLite, les modifications du schéma sont atomiques donc cela ne quittera pas votre base de données dans un état bizarre si la migration échoue. Avec MySQL, vous devez être plus prudent.

D'après la documentation de l'API Rails, les options possibles pour le type sont:

: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 wappos souligné, vous pouvez utiliser les options auxiliaires comme: limite à dire ActiveRecord comment vous voulez que la colonne soit. Donc, vous devez utiliser la: colonne int avec une plus grande. Limite

Si quelqu'un a besoin pour travailler 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 de chargement paresseux dans Rails 3.2 (et versions antérieures) peut-être même, ne sera pas ActiveRecord::ConnectionAdapters::PostgreSQLAdapter nécessaire jusqu'à ce que vous établissez la connexion de base de données.

Dans rails4, vous pouvez le faire.

Voici un exemple pour créer un modèle dans Dummy & postgres serial8,

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

Qu'est-ce qu'il a fait:

  • Il utilise primary key que le type d'identification, qui est 64 nombre entier de bits, et le définir comme timestamptz.
  • Il utilise comme type de <=> datetime, qui contiennent les informations de fuseau horaire, ce qui est important pour une application qui traversent plusieurs fuseaux horaires.

Rails 3, MySQL:

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

ne me donne pas un bigint, seul un int. Cependant,

t.column :twitter_id, 'bigint'

fonctionne très bien. (Bien qu'il ne me lier à MySQL.)

Emprunts d'autres solutions, adaptées pour ce qui a fonctionné pour moi récemment.

Ajouter un fichier à config/initializers. Il déclare un nouveau type de colonne (adapté de la suggestion de chookeat).

ActiveRecord::ConnectionAdapters::Mysql2Adapter::NATIVE_DATABASE_TYPES[:long_primary_key] = "BIGINT(20) DEFAULT NULL auto_increment PRIMARY KEY"

qui utilisent un migrations à long id sont en tant que tels:

    create_table :notification_logs, :id => false do |t|

      t.column :id, :long_primary_key
      # ...
    end

J'ai écrit un petit bijou appelé activerecord-native_db_types_override qui vous permet de modifier les types de données qui seront utilisées dans vos migrations.

Dans votre Gemfile, ajouter:

gem 'activerecord-native_db_types_override'

puis dans config / environment.rb, utiliser de longues ids dans Postgres, ajouter:

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

Voir son README pour plus d'informations mises à jour.

Vous pouvez le faire comme ceci:

class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users, id: :bigserial do |t|
      t.string :name
    end
  end
end

Correction à la façon de modifier le type de colonne par défaut primary key:

Au lieu de:

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

vous devez faire:

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

ou bien vous ne serez pas en mesure d'ajouter des restrictions dans la foreign key couche de base de données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top