Come utilizzare tempo id nelle applicazioni Rails?
-
21-08-2019 - |
Domanda
Come posso cambiare il (default) di tipo per gli ID di ActiveRecord? int non è abbastanza lungo, preferirei lungo. Sono rimasto sorpreso che non c'è: a lungo per le migrazioni - si fa basta usare qualche decimale
Soluzione
http://moeffju.net/blog/using- bigint-colonne-in-rails-migrazioni
class CreateDemo < ActiveRecord::Migration
def self.up
create_table :demo, :id => false do |t|
t.integer :id, :limit => 8
end
end
end
- Vedere l'opzione
:id => false
che disabilita la creazione automatica del campo id - La linea
t.integer :id, :limit => 8
produrrà un campo intero a 64 bit
Altri suggerimenti
Per impostare il default tipo di colonna chiave primaria , i file di migrazione non sono il posto a pasticciare con.
Invece, basta attaccare questo alla parte inferiore del vostro config/environment.rb
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
E tutte le tabelle devono essere create con il tipo di colonna destinata al id
:
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
Dopo che hai fatto quello che hai stabilito di fare ... la prossima domanda è probabilmente "Come faccio a fare le mie colonne chiave esterna lo stesso tipo di colonna?" dal momento che non ha senso avere chiave primaria people.id
come bigint(20) unsigned
, e person_id
essere int(11)
o qualsiasi altra cosa?
Per queste colonne, è possibile fare riferimento agli altri suggerimenti, per es.
t.column :author_id, 'BIGINT UNSIGNED'
t.integer :author_id, :limit => 8
Aggiorna : @Notinlist, per usare colonna arbitraria per la chiave primaria su tavoli arbitrari che devi fare il create_table-change_column
ballo:
create_table(:users) do |t|
# column definitions here..
end
change_column :users, :id, :float # or some other column type
es. se volevo guid
invece di interi incremento automatico,
create_table(:users, :primary_key => 'guid') do |t|
# column definitions here..
end
change_column :users, :guid, :string, :limit => 36
Questo è difficile da impostare per la chiave primaria con le migrazioni perché Rails lo mette automaticamente.
È possibile modificare qualsiasi colonna in seguito in questo modo:
change_column :foobars, :something_id, 'bigint'
È possibile specificare gli ID non primarie come tipi personalizzati nel migrazione iniziale in questo modo:
create_table :tweets do |t|
t.column :twitter_id, 'bigint'
t.column :twitter_in_reply_to_status_id, 'bigint'
end
Dove ho "bigint" è possibile inserire qualsiasi testo che il database potrebbe utilizzare per il tipo di colonna di database che si desidera utilizzare (ad esempio, "unsigned long").
Se avete bisogno della colonna id ad essere un bigint, il modo più semplice per farlo sarebbe quello di creare la tabella, quindi modificare la colonna nella stessa migrazione con change_column.
Con PostgreSQL e SQLite, le modifiche dello schema sono atomiche quindi questo non lascerà il database in uno stato strano se la migrazione non riesce. Con MySQL è necessario essere più attenti.
In base alla documentazione delle API Rails, le possibili opzioni per il tipo sono:
:string
:text
:integer
:float
:decimal
:datetime
:timestamp
:time
:date
:binary
:boolean
È possibile utilizzare: decimale, oppure è possibile eseguire un comando direttamente se avete bisogno di:
class MyMigration
def self.up
execute "ALTER TABLE my_table ADD id LONG"
end
end
Come wappos sottolineato, è possibile utilizzare le opzioni ausiliarie come: limite a dire ActiveRecord quanto grande si vuole che la colonna sia. Quindi, si può usare il: colonna int con una più grande:. Limite
Se qualcuno ha bisogno di questo per lavorare con PostgreSQL, creare un inizializzatore in questo modo:
# config/initializers/bigint_primary_keys.rb
ActiveRecord::Base.establish_connection
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = 'bigserial primary key'
A causa di lazy loading in Rails 3.2 (e versioni forse anche prima), ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
non saranno necessari fino a quando si stabilisce la connessione al database.
In rails4
, si può fare.
In seguito è riportato un esempio di creare un modello Dummy
in 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
Quello che ha fatto:
- Si usa
primary key
come tipo id, che è a 64 bit interi, e definire cometimestamptz
. - Si usa <=> come tipo datetime, che contengono le informazioni fuso orario, questo è importante per un'applicazione che vanno su più fusi orari.
Rails 3, MySQL:
t.column :foobar, :int, :limit => 8
Non mi dare un bigint, solo un int. Tuttavia,
t.column :twitter_id, 'bigint'
funziona bene. (Anche se non legarmi a MySQL.)
Prendendo in prestito da altre soluzioni, rettificato per quello che ha funzionato per me di recente.
Aggiungi a un file in config/initializers
. Dichiara un nuovo tipo di colonna (adattato da suggerimento di chookeat).
ActiveRecord::ConnectionAdapters::Mysql2Adapter::NATIVE_DATABASE_TYPES[:long_primary_key] = "BIGINT(20) DEFAULT NULL auto_increment PRIMARY KEY"
Le migrazioni che utilizzano una lunga id sono in quanto tali:
create_table :notification_logs, :id => false do |t|
t.column :id, :long_primary_key
# ...
end
ho scritto una gemma chiamata activerecord-native_db_types_override che consente di modificare i tipi di dati che saranno utilizzati nelle migrazioni.
Nel vostro Gemfile, aggiungere:
gem 'activerecord-native_db_types_override'
poi in config / environment.rb, di utilizzare lunghi ids in Postgres, aggiungere:
NativeDbTypesOverride.configure({
postgres: {
primary_key: { name: "bigserial primary key"}
}
})
README per up-to-date informazioni.
Si può fare 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 a come cambiare il tipo di colonna primary key
predefinito:
Al posto di:
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
si dovrebbe fare:
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT(8) UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
, altrimenti non sarà in grado di aggiungere foreign key
restrizioni nel livello di database.