Ruby on Rails
Migrazioni di ActiveRecord
Ricerca…
Parametri
Tipo di colonna | Descrizione |
---|---|
:primary_key | Chiave primaria |
:string | Tipo di dati stringa più breve. Consente l'opzione limit per il numero massimo di caratteri. |
:text | Quantità di testo più lunga Consente l'opzione limit per il numero massimo di byte. |
:integer | Numero intero. Consente l'opzione limit per il numero massimo di byte. |
:bigint | Intero più grande |
:float | Galleggiante |
:decimal | Numero decimale con precisione variabile. Permette precision e opzioni di scale . |
:numeric | Permette precision e opzioni di scale . |
:datetime | Oggetto DateTime per date / orari. |
:time | Tempo oggetto per tempi. |
:date | Data dell'oggetto per le date. |
:binary | Dati binari Consente l'opzione limit per il numero massimo di byte. |
:boolean | booleano |
Osservazioni
La maggior parte dei file di migrazione risiede nella directory
db/migrate/
. Sono identificati da un timestamp UTC all'inizio del nome del file:YYYYMMDDHHMMSS_create_products.rb
.Il comando di comando dei
rails generate
può essere abbreviato inrails g
.Se a
:type
non viene passato a un campo, il valore predefinito è una stringa.
Esegui una migrazione specifica
Per eseguire una migrazione specifica verso l'alto o verso il basso, utilizzare db:migrate:up
o db:migrate:down
.
Una migrazione specifica:
rake db:migrate:up VERSION=20090408054555
rails db:migrate:up VERSION=20090408054555
Giù una migrazione specifica:
rake db:migrate:down VERSION=20090408054555
rails db:migrate:down VERSION=20090408054555
Il numero di versione nei comandi precedenti è il prefisso numerico nel nome file della migrazione. Ad esempio, per migrare alla migrazione 20160515085959_add_name_to_users.rb
, si utilizzerà 20160515085959
come numero di versione.
Crea una tabella di join
Per creare una tabella di join tra students
e courses
, eseguire il comando:
$ rails g migration CreateJoinTableStudentCourse student course
Questo genererà la seguente migrazione:
class CreateJoinTableStudentCourse < ActiveRecord::Migration[5.0]
def change
create_join_table :students, :courses do |t|
# t.index [:student_id, :course_id]
# t.index [:course_id, :student_id]
end
end
end
Esecuzione di migrazioni in diversi ambienti
Per eseguire le migrazioni nell'ambiente di test
, eseguire questo comando shell:
rake db:migrate RAILS_ENV=test
A partire da Rails 5.0, puoi utilizzare le rails
anziché il rake
:
rails db:migrate RAILS_ENV=test
Aggiungi una nuova colonna a una tabella
Per aggiungere un nuovo name
colonna alla tabella users
, eseguire il comando:
rails generate migration AddNameToUsers name
Questo genera la seguente migrazione:
class AddNameToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :name, :string
end
end
Quando il nome della migrazione è del formato AddXXXToTABLE_NAME
seguito dall'elenco di colonne con tipi di dati, la migrazione generata conterrà le istruzioni add_column
appropriate.
Aggiungi una nuova colonna con un indice
Per aggiungere una nuova email
indicizzata alla colonna degli users
, eseguire il comando:
rails generate migration AddEmailToUsers email:string:index
Questo genererà la seguente migrazione:
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :email, :string
add_index :users, :email
end
end
Rimuovi una colonna esistente da una tabella
Per rimuovere il name
colonna esistente dalla tabella degli users
, eseguire il comando:
rails generate migration RemoveNameFromUsers name:string
Questo genererà la seguente migrazione:
class RemoveNameFromUsers < ActiveRecord::Migration[5.0]
def change
remove_column :users, :name, :string
end
end
Quando il nome della migrazione è nella forma RemoveXXXFromYYY
seguito dall'elenco di colonne con tipi di dati, la migrazione generata conterrà le istruzioni remove_column
appropriate.
Sebbene non sia necessario specificare il tipo di dati (ad esempio :string
) come parametro per remove_column
, è altamente raccomandato. Se il tipo di dati non è specificato, la migrazione non sarà reversibile.
Aggiungi una colonna di riferimento a una tabella
Per aggiungere un riferimento a un team
alla tabella users
, esegui questo comando:
$ rails generate migration AddTeamRefToUsers team:references
Questo genera la seguente migrazione:
class AddTeamRefToUsers < ActiveRecord::Migration[5.0]
def change
add_reference :users, :team, foreign_key: true
end
end
Quella migrazione creerà una colonna team_id
nella tabella degli users
.
Se si desidera aggiungere un index
appropriato e una foreign_key
nella colonna aggiunta, modificare il comando in rails generate migration AddTeamRefToUsers team:references:index
. Questo genererà la seguente migrazione:
class AddTeamRefToUsers < ActiveRecord::Migration
def change
add_reference :users, :team, index: true
add_foreign_key :users, :teams
end
end
Se si desidera denominare la colonna di riferimento diversa da quella che viene generata automaticamente da Rails, aggiungere quanto segue alla migrazione: (Ad esempio, è possibile chiamare l' User
che ha creato il Post
come Author
nella tabella Post
)
class AddAuthorRefToPosts < ActiveRecord::Migration
def change
add_reference :posts, :author, references: :users, index: true
end
end
Crea una nuova tabella
Per creare una nuova tabella users
con il name
e lo salary
delle colonne, esegui il comando:
rails generate migration CreateUsers name:string salary:decimal
Questo genererà la seguente migrazione:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.decimal :salary
end
end
end
Quando il nome della migrazione è del formato CreateXXX
seguito dall'elenco di colonne con tipi di dati, verrà generata una migrazione che crea la tabella XXX
con le colonne elencate.
Aggiunta di più colonne a una tabella
Per aggiungere più colonne a una tabella, separare il field:type
coppie con spazi quando si utilizzano i rails generate migration
comando di rails generate migration
.
La sintassi generale è:
rails generate migration NAME [field[:type][:index] field[:type][:index]] [options]
Ad esempio, quanto segue aggiungerà i campi name
, salary
ed email
alla tabella users
:
rails generate migration AddDetailsToUsers name:string salary:decimal email:string
Che genera la seguente migrazione:
class AddDetailsToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :name, :string
add_column :users, :salary, :decimal
add_column :users, :email, :string
end
end
Esecuzione di migrazioni
Esegui comando:
rake db:migrate
rails db:migrate
Specificando la versione di destinazione verranno eseguite le migrazioni richieste (su, giù, cambia) fino a quando non avrà raggiunto la versione specificata. Qui, il version number
è il prefisso numerico sul nome file della migrazione.
rake db:migrate VERSION=20080906120000
rails db:migrate VERSION=20080906120000
Migrazioni di rollback
Per eseguire il rollback
della migrazione più recente, ripristinando il metodo di change
o eseguendo il metodo down
. Esegui comando:
rake db:rollback
rails db:rollback
Ripristina le ultime 3 migrazioni
rake db:rollback STEP=3
rails db:rollback STEP=3
STEP
fornisce il numero di migrazioni da ripristinare.
Rollback di tutte le migrazioni
rake db:rollback VERSION=0
rails db:rollback VERSION=0
Cambiare le tabelle
Se hai creato una tabella con uno schema sbagliato, il modo più semplice per cambiare le colonne e le loro proprietà è change_table
. Esamina il seguente esempio:
change_table :orders do |t|
t.remove :ordered_at # removes column ordered_at
t.string :skew_number # adds a new column
t.index :skew_number #creates an index
t.rename :location, :state #renames location column to state
end
La precedente migrazione modifica gli orders
una tabella. Ecco una descrizione riga per riga delle modifiche:
-
t.remove :ordered_at
rimuove la colonnaordered_at
dagliorders
della tabella. -
t.string :skew_number
aggiunge una nuova colonna di tipo stringa denominataskew_number
nella tabella degliorders
. -
t.index :skew_number
aggiunge un indice sulla colonnaskew_number
nella tabella degliorders
. -
t.rename :location, :state
rinomina lalocation
colonna nellaorders
tabellastate
.
Aggiungi una colonna univoca a una tabella
Per aggiungere una nuova email
colonna unica agli users
, eseguire il seguente comando:
rails generate migration AddEmailToUsers email:string:uniq
Questo creerà la seguente migrazione:
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :email, :string
add_index :users, :email, unique: true
end
end
Cambia il tipo di una colonna esistente
Per modificare una colonna esistente in Rails con una migrazione, eseguire il seguente comando:
rails g migration change_column_in_table
Questo creerà un nuovo file di migrazione nella directory db/migration
(se non esiste già), che conterrà il file con il prefisso timestamp e il nome del file di migrazione che contiene il contenuto seguente:
def change
change_column(:table_name, :column_name, :new_type)
end
Guida delle guide - Modifica delle colonne
Un metodo più lungo ma più sicuro
Il codice precedente impedisce all'utente di interrompere la migrazione. È possibile evitare questo problema suddividendo il metodo di change
in metodi separati up
e down
:
def up
change_column :my_table, :my_column, :new_type
end
def down
change_column :my_table, :my_column, :old_type
end
Ripeti le migrazioni
È possibile eseguire il rollback e quindi eseguire nuovamente la migrazione utilizzando il comando redo
. Questo è fondamentalmente un collegamento che combina il rollback
e migrate
attività.
Esegui comando:
rake db:migrate:redo
rails db:migrate:redo
È possibile utilizzare il parametro STEP
per tornare più di una versione.
Ad esempio, per tornare indietro 3 migrazioni:
rake db:migrate:redo STEP=3
rails db:migrate:redo STEP=3
Aggiungi colonna con valore predefinito
L'esempio seguente aggiunge un admin
colonna alla tabella users
e assegna a tale colonna il valore predefinito false
.
class AddDetailsToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :admin, :boolean, default: false
end
end
Le migrazioni con valori predefiniti potrebbero impiegare molto tempo in tabelle di grandi dimensioni, ad esempio PostgreSQL. Questo perché ogni riga dovrà essere aggiornata con il valore predefinito per la colonna appena aggiunta. Per aggirare questo problema (e ridurre i tempi di inattività durante le distribuzioni), puoi dividere la migrazione in tre passaggi:
- Aggiungi un
add_column
-migration simile a quello sopra, ma non impostare alcun valore predefinito - Distribuisci e aggiorna la colonna in un'attività rake o sulla console mentre la tua app è in esecuzione. Assicurati che l'applicazione scriva già i dati su quella colonna per le righe nuove / aggiornate.
- Aggiungi un'altra migrazione
change_column
, che quindi modifica il valore predefinito di tale colonna sul valore predefinito desiderato
Vieta valori nulli
Per evitare valori null
nelle colonne della tabella, aggiungi il parametro :null
alla tua migrazione, in questo modo:
class AddPriceToProducts < ActiveRecord::Migration
def change
add_column :products, :float, null: false
end
end
Controllo dello stato della migrazione
Possiamo controllare lo stato delle migrazioni eseguendo
rake db:migrate:status
rails db:migrate:status
L'output sarà simile a questo:
Status Migration ID Migration Name
--------------------------------------------------
up 20140711185212 Create documentation pages
up 20140724111844 Create nifty attachments table
up 20140724114255 Create documentation screenshots
up 20160213170731 Create owners
up 20160218214551 Create users
up 20160221162159 ********** NO FILE **********
up 20160222231219 ********** NO FILE **********
Sotto il campo dello stato, up
significa che la migrazione è stata eseguita e down
significa che è necessario eseguire la migrazione.
Crea una colonna di hstore
Hstore
colonne di Hstore
possono essere utili per memorizzare le impostazioni. Sono disponibili nei database PostgreSQL dopo aver abilitato l'estensione.
class CreatePages < ActiveRecord::Migration[5.0]
def change
create_table :pages do |t|
enable_extension 'hstore' unless extension_enabled?('hstore')
t.hstore :settings
t.timestamps
end
end
end
Aggiungi un riferimento personale
Un riferimento personale può essere utile per costruire un albero gerarchico. Questo può essere ottenuto con add_reference
in una migrazione.
class AddParentPages < ActiveRecord::Migration[5.0]
def change
add_reference :pages, :pages
end
end
La colonna chiave esterna sarà pages_id
. Se si desidera decidere il nome della colonna chiave esterna, è necessario creare prima la colonna e aggiungere il riferimento dopo.
class AddParentPages < ActiveRecord::Migration[5.0]
def change
add_column :pages, :parent_id, :integer, null: true, index: true
add_foreign_key :pages, :pages, column: :parent_id
end
end
Crea una colonna di array
Una colonna di array
è supportata da PostgreSQL. Rails convertirà automaticamente un array PostgreSQL in un array Ruby e viceversa.
Crea una tabella con una colonna di array
:
create_table :products do |t|
t.string :name
t.text :colors, array: true, default: []
end
Aggiungi una colonna di array
a una tabella esistente:
add_column :products, :colors, array: true, default: []
Aggiungi un indice per una colonna di array
:
add_index :products, :colors, using: 'gin'
Aggiunta di un vincolo NOT NULL ai dati esistenti
Supponiamo che tu voglia aggiungere una chiave company_id
alla tabella users
e che tu debba avere un vincolo NOT NULL
su di essa. Se hai già dati negli users
, dovrai farlo in più passaggi.
class AddCompanyIdToUsers < ActiveRecord::Migration
def up
# add the column with NULL allowed
add_column :users, :company_id, :integer
# make sure every row has a value
User.find_each do |user|
# find the appropriate company record for the user
# according to your business logic
company = Company.first
user.update!(company_id: company.id)
end
# add NOT NULL constraint
change_column_null :users, :company_id, false
end
# Migrations that manipulate data must use up/down instead of change
def down
remove_column :users, :company_id
end
end