Come utilizzare l’ID lungo nelle applicazioni Rails?

Come posso cambiare il tipo (predefinito) per gli ID di ActiveRecord? int non è abbastanza lungo, preferirei a lungo. Mi ha sorpreso che non ci sia: lunga per le migrazioni – si usa solo qualche decimale?

Crediti per 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 
  • Vedi l’opzione :id => false che disabilita la creazione automatica del campo id
  • The t.integer :id, :limit => 8 line produrrà un campo intero a 64 bit

Per impostare il tipo di colonna della chiave primaria di default , i file di migrazione non sono il luogo in cui fare confusione.

Invece, limitatevi a posizionarlo nella parte inferiore di config/environment.rb

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

E tutte le tue tabelle dovrebbero essere create con il tipo di colonna previsto per l’ id :

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

Dopo aver fatto ciò che hai deciso di fare … la prossima domanda è probabilmente “Come faccio a rendere le colonne della mia chiave esterna lo stesso tipo di colonna?” dal momento che non ha senso avere la chiave primaria people.id come bigint(20) unsigned e person_id be int(11) o qualcos’altro?

Per quelle colonne, puoi fare riferimento agli altri suggerimenti, ad es

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

AGGIORNAMENTO : @Notinlist, per utilizzare la colonna arbitraria per la chiave primaria su tabelle arbitrarie è necessario eseguire la danza create_table-change_column :

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

ad esempio se volessi guid invece di numeri interi a incremento automatico,

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

È difficile impostare la chiave primaria con le migrazioni perché Rails lo inserisce automaticamente.

Puoi modificare qualsiasi colonna in seguito in questo modo:

change_column :foobars, :something_id, 'bigint'

È ansible specificare ID non primari come tipi personalizzati nella migrazione iniziale come questo:

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

Dove ho “bigint” puoi inserire qualsiasi testo che il tuo database userebbe per il tipo di colonna del database che vuoi usare (es. “Unsigned long”).

Se hai bisogno che la tua colonna id sia un bigint, il modo più semplice per farlo sarebbe creare la tabella, quindi cambiare la colonna nella stessa migrazione con change_column.

Con PostgreSQL e SQLite, le modifiche dello schema sono atomiche, quindi questo non lascerà il tuo database in uno stato strano se la migrazione fallisce. Con MySQL devi essere più attento.

Secondo la documentazione dell’API di Rails, le possibili opzioni per il tipo sono:

 :string :text :integer :float :decimal :datetime :timestamp :time :date :binary :boolean 

È ansible utilizzare: decimale, oppure è ansible eseguire direttamente un comando se è necessario:

 class MyMigration def self.up execute "ALTER TABLE my_table ADD id LONG" end end 

Come indicato dai wappo, puoi usare le opzioni ausiliarie come: limit per dire a ActiveRecord quanto grande vuoi che sia la colonna. Quindi useresti la colonna: int con un limite più grande.

Se qualcuno ha bisogno che funzioni con PostgreSQL, crea un inizializzatore come questo:

 # config/initializers/bigint_primary_keys.rb ActiveRecord::Base.establish_connection ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = 'bigserial primary key' 

A causa del caricamento lento in Rails 3.2 (e forse anche nelle versioni precedenti), ActiveRecord::ConnectionAdapters::PostgreSQLAdapter non sarà richiesto fino a quando non si stabilirà la connessione al database.

In rails4 , puoi farlo.

Di seguito è riportato un esempio per creare un modello Dummy in rails4 e 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 

Che cosa ha fatto:

  • Usa serial8 come tipo id, che è un numero intero a 64 bit e lo definisce come primary key .
  • Usa timestamptz come tipo datetime, che contiene le informazioni sul fuso orario, questo è importante per un’applicazione che attraversa più fusi orari.

Rails 3, MySQL:

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

Non mi dà un bigint, solo un int. Però,

 t.column :twitter_id, 'bigint' 

funziona bene. (Anche se mi lega a MySQL.)

Prendendo in prestito da altre soluzioni, adattato per ciò che ha funzionato per me di recente.

Aggiungi a un file in config/initializers . Dichiara un nuovo tipo di colonna (adattato dal suggerimento di chookeat).

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

Le migrazioni che utilizzano un ID lungo sono come tali:

  create_table :notification_logs, :id => false do |t| t.column :id, :long_primary_key # ... end 

Ho scritto una gem chiamata activerecord-native_db_types_override che ti consente di modificare i tipi di dati che verranno utilizzati nelle tue migrazioni.

Nel tuo Gemfile, aggiungi:

 gem 'activerecord-native_db_types_override' 

quindi in config / environment.rb, per usare gli identificatori lunghi in postgres, aggiungere:

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

Vedi il suo README per informazioni aggiornate.

Puoi farlo in questo modo:

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

Correzione su come modificare il tipo di colonna primary key predefinita:

Invece di:

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

dovresti fare:

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

altrimenti non sarai in grado di aggiungere restrizioni di foreign key nel livello del database.