Come posso rinominare una colonna di database in una migrazione Ruby on Rails?
-
22-09-2019 - |
Domanda
I erroneamente chiamato un hased_password
colonna invece hashed_password
.
Come faccio ad aggiornare lo schema del database, utilizzando la migrazione per rinominare questa colonna?
Soluzione
rename_column :table, :old_column, :new_column
Aggiornamento:
Probabilmente si vorrà creare una migrazione separata per fare questo. (Rinomina FixColumnName come si vedrà)
script/generate migration FixColumnName
# creates db/migrate/xxxxxxxxxx_fix_column_name.rb
Quindi modificare la migrazione a fare la tua volontà.
# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
def self.up
rename_column :table_name, :old_column, :new_column
end
def self.down
# rename back if you need or do something else or do nothing
end
end
Un aggiornamento per Rails 3.1
si applicano ancora po ', la up
e down
metodi. Rotaie 3.1 riceve un metodo change
che "sa come migrare il database e invertire quando la migrazione è rotolato indietro senza la bisogno di scrivere un metodo separato down "
rails g migration FixColumnName
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Se vi capita di avere un sacco di colonne per rinominare, o qualcosa che avrebbe richiesto di ripetere il nome della tabella più e più volte.
rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...
Si potrebbe utilizzare change_table
per mantenere le cose un po 'più ordinato.
class FixColumnNames < ActiveRecord::Migration
def change
change_table :table_name do |t|
t.rename :old_column1, :new_column1
t.rename :old_column2, :new_column2
...
end
end
end
Grazie, Luke
&& Turadg
, per portare l'argomento.
Poi, proprio db:migrate
come al solito o comunque si va sulla tua attività.
Aggiornamento di rotaie 4
Durante la creazione di Migration
adottata per le colonna, rotaie 4 genera un metodo change
anziché up
e down
come menzionato nella risposta precedente. Il metodo change
generato è il seguente:
$ > rails g migration ChangeColumnName
che creerà un file di migrazione simile a questo:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Altri suggerimenti
IMO, in questo caso, un uso migliore rake db:rollback
. Quindi modificare la migrazione e di nuovo tipo rake db:migrate
. Tuttavia, se si dispone di dati nella colonna non si vuole perdere, quindi utilizzare rename_column
.
Se la colonna è già popolata con i dati e vivono in produzione, mi consiglia un approccio graduale, in modo da evitare i tempi di fermo della produzione in attesa che le migrazioni.
Per prima cosa mi piacerebbe creare una migrazione db per aggiungere colonne con il nuovo nome (s) e li popolano con i valori del vecchio nome della colonna.
class AddCorrectColumnNames < ActiveRecord::Migration
def up
add_column :table, :correct_name_column_one, :string
add_column :table, :correct_name_column_two, :string
puts 'Updating correctly named columns'
execute "UPDATE table_name SET correct_name_column_one = old_name_column_one, correct_name_column_two = old_name_column_two"
end
end
def down
remove_column :table, :correct_name_column_one
remove_column :table, :correct_name_column_two
end
end
Poi mi piacerebbe commesso proprio questo cambiamento, e spingere il cambiamento in produzione.
git commit -m 'adding columns with correct name'
Poi, una volta che il commit è stato spinto in produzione, mi piacerebbe correre.
Production $ bundle exec rake db:migrate
Poi mi piacerebbe aggiornare tutte le viste / controller che fa riferimento al vecchio nome della colonna con il nuovo nome di colonna. Corri attraverso la mia suite di test, e si impegnano solo quei cambiamenti. (Dopo essersi assicurato che stava lavorando a livello locale e passando tutti i test prima!)
git commit -m 'using correct column name instead of old stinky bad column name'
Poi mi piacerebbe spinta che impegnano alla produzione.
A questo punto è possibile rimuovere la colonna originale, senza preoccuparsi di alcun tipo di inattività associati alla migrazione stessa.
class RemoveBadColumnNames < ActiveRecord::Migration
def up
remove_column :table, :old_name_column_one
remove_column :table, :old_name_column_two
end
def down
add_column :table, :old_name_column_one, :string
add_column :table, :old_name_column_two, :string
end
end
Quindi spingere questa ultima migrazione verso la produzione ed eseguire bundle exec rake db:migrate
in background.
Mi rendo conto che è un po 'più complicato di un processo, ma preferirei farlo che hanno problemi con la mia migrazione di produzione.
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
Sotto Available Transformations
rename_column(table_name, column_name, new_column_name):
Rinomina una colonna, ma mantiene il tipo e il contenuto.
Eseguire il comando qui per creare un file di migrazione:
rails g migration ChangeHasedPasswordToHashedPassword
Poi nel file generato nella cartella db/migrate
, scrivere rename_column
come di seguito:
class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Da API:
rename_column(table_name, column_name, new_column_name)
Si rinomina una colonna ma mantiene il tipo e il contenuto rimane lo stesso.
Alcune versioni di Ruby on Rails sostegno per su / giù metodo per la migrazione e se si dispone di up / down metodo nella migrazione, allora:
def up
rename_column :table_name, :column_old_name, :column_new_name
end
def down
rename_column :table_name, :column_new_name, :column_old_name
end
Se avete il metodo change
nella migrazione, allora:
def change
rename_column :table_name, :column_old_name, :column_new_name
end
Per ulteriori informazioni è possibile spostare: Ruby on Rails - Migrazioni o attivi Registra Migrazioni .
Se il codice non è condiviso con altro, quindi migliore opzione è quella di fare proprio rake db:rollback
quindi modificare il nome della colonna in migrazione e rake db:migrate
. Ecco fatto
E si può scrivere un'altra migrazione di rinominare la colonna
def change
rename_column :table_name, :old_name, :new_name
end
Questo è tutto.
Se avete bisogno di cambiare i nomi delle colonne è necessario creare un segnaposto per evitare una duplicare errore nome di colonna . Ecco un esempio:
class SwitchColumns < ActiveRecord::Migration
def change
rename_column :column_name, :x, :holder
rename_column :column_name, :y, :x
rename_column :column_name, :holder, :y
end
end
Come opzione alternativa, se non si è sposata con l'idea di migrazioni, v'è una gemma convincente per ActiveRecord che gestirà il nome cambia automaticamente per voi, DataMapper stile. Tutto ciò che fai è cambiare il nome della colonna nel modello (e assicurarsi di mettere Model.auto_upgrade! nella parte inferiore del vostro model.rb) e viola! Il database è aggiornato in tempo reale.
https://github.com/DAddYE/mini_record
Nota: Sarà necessario bombardare db / schema.rb per prevenire i conflitti
Ancora in fase beta e, ovviamente, non per tutti, ma ancora una scelta interessante (Attualmente sto usando in due applicazioni di produzione non banali senza problemi)
Se l'attuale dati non è importante per voi, si può semplicemente prendere giù la migrazione originale utilizzando:
rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'
Senza le virgolette, quindi apportare le modifiche nella migrazione originale ed eseguire di nuovo la migrazione da:
rake db:migrate
È sufficiente creare una nuova migrazione, e in un blocco, utilizzare rename_column
come di seguito.
rename_column :your_table_name, :hased_password, :hashed_password
Per Ruby on Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
Manualmente si può utilizzare il seguente metodo:
Possiamo modificare la migrazione manualmente come:
-
Apri
app/db/migrate/xxxxxxxxx_migration_file.rb
-
Aggiornamento
hased_password
ahashed_password
-
Eseguire il comando seguente
$> rake db:migrate:down VERSION=xxxxxxxxx
Poi si rimuoverà la migrazione:
$> rake db:migrate:up VERSION=xxxxxxxxx
Si aggiungerà la migrazione con il cambio aggiornato.
Genera il file di migrazione:
rails g migration FixName
Crea # db / migrate / xxxxxxxxxx.rb
Modifica la migrazione a fare la tua volontà.
class FixName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Esegui rails g migration ChangesNameInUsers
(o qualsiasi altra cosa che si desidera nominarlo)
Aprire il file di migrazione che è stato appena generato e aggiungere questa riga nel metodo (tra def change
e end
):
rename_column :table_name, :the_name_you_want_to_change, :the_new_name
Salvare il file ed eseguire rake db:migrate
nella console
Controlla il tuo schema.db
per vedere se il nome è effettivamente cambiato nel database!
Spero che questo aiuti:)
$: rails g migration RenameHashedPasswordColumn
invoke active_record
create db/migrate/20160323054656_rename_hashed_password_column.rb
Aprire il file di migrazione e modificare il file come qui sotto (inserisci il tuo table_name
originale)
class RenameHashedPasswordColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
def change
rename_column :table_name, :old_column_name, :new_column_name
end
Genera una migrazione Ruby on Rails :
$:> rails g migration Fixcolumnname
Inserire il codice nel file di migrazione (XXXXXfixcolumnname.rb) :
class Fixcolumnname < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
BACIO . Tutto quello che serve è tre semplici passaggi. I seguenti lavori per Rails 5.2 .
1. Creare una migrazione
-
rails g migration RenameNameToFullNameInStudents
-
rails g RenameOldFieldToNewFieldInTableName
- in questo modo è perfettamente chiaro a manutentori del codice di base in seguito. (Utilizzare un plurale per il nome della tabella).
2. Modificare la migrazione
# I prefer to explicitly write the
upand
downmethods.
# ./db/migrate/20190114045137_rename_name_to_full_name_in_students.rb
class RenameNameToFullNameInStudents < ActiveRecord::Migration[5.2]
def up
# rename_column :table_name, :old_column, :new_column
rename_column :students, :name, :full_name
end
def down
# Note that the columns are reversed
rename_column :students, :full_name, :name
end
end
3. Eseguire il tuo migrazioni
rake db:migrate
E tu sei fuori per le gare!
Aprire il Ruby on Rails console e digitare:
ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
Ci sono due modi per farlo:
-
In questo tipo viene eseguito automaticamente il codice inverso, quando rollback.
def change rename_column :table_name, :old_column_name, :new_column_name end
-
Per questo tipo, viene eseguito il metodo quando
rake db:migrate
e corre il metodo verso il basso quandorake db:rollback
:def self.up rename_column :table_name, :old_column_name, :new_column_name end def self.down rename_column :table_name,:new_column_name,:old_column_name end
Sono su rotaie 5.2, e cercando di rinominare una colonna su un User disposizione testamentaria.
il bit rename_column
lavorato per me, ma il :table_name
singolare ha gettato un "tavolo utente non trovato" errore. Plurale ha lavorato per me.
rails g RenameAgentinUser
Quindi modificare file di migrazione a questo:
rename_column :users, :agent?, :agent
Dove: agente? è il vecchio nome della colonna.
Basta generare migrazione utilizzando il comando
rails g migration rename_hased_password
Dopo che modifica la migrazione Aggiungete la seguente riga nel metodo di cambiamento
rename_column :table, :hased_password, :hashed_password
Questo dovrebbe fare il trucco.
Rails 5 modifiche di migrazione
es:
rotaie student_name g studente modello: Età stringa: intero
Se si desidera modificare student_name colonna come nome
Nota: - se non si esegue rotaie db: la migrazione
È possibile farlo seguendo i passaggi
rotaie student_name d studente modello: Età stringa: intero
Questo file di migrazione rimuoverà generato, ora è possibile correggere il vostro nome della colonna
rotaie g modello nome dello Studente: Età stringa: intero
Se è stato migrato (rotaie db: migrate), opzioni per cambiare il nome della colonna seguente
rotaie g migrazione RemoveStudentNameFromStudent student_name: stringa
rotaie nome g migrazione AddNameToStudent: stringa
Aggiorna - Un primo cugino di CREATE_TABLE è change_table, utilizzato per modificare le tabelle esistenti. E 'utilizzato in modo simile al CREATE_TABLE ma l'oggetto ceduto al blocco sa più trucchi. Ad esempio:
class ChangeBadColumnNames < ActiveRecord::Migration
def change
change_table :your_table_name do |t|
t.rename :old_column_name, :new_column_name
end
end
end
In questo modo è più efficace se facciamo con altri metodi alter quali: rimuovere / aggiungere index / index rimuovere / aggiungere colonna, ad esempio possiamo fare ulteriori come:
# Rename
t.rename :old_column_name, :new_column_name
# Add column
t.string :new_column
# Remove column
t.remove :removing_column
# Index column
t.index :indexing_column
#...