Ho erroneamente chiamato una colonna hased_password
invece di hashed_password
.
Come posso aggiornare lo schema del database, usando la migrazione per rinominare questa colonna?
Ho erroneamente chiamato una colonna hased_password
invece di hashed_password
.
Come posso aggiornare lo schema del database, usando la migrazione per rinominare questa colonna?
Risposte:
rename_column :table, :old_column, :new_column
Probabilmente vorrai creare una migrazione separata per farlo. (Rinomina FixColumnName
come vuoi.):
script/generate migration FixColumnName
# creates db/migrate/xxxxxxxxxx_fix_column_name.rb
Quindi modifica la migrazione per 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
Per Rails 3.1 utilizzare:
Mentre i metodi up
e down
continuano a essere validi, Rails 3.1 riceve un change
metodo che "sa come migrare il database e invertirlo quando la migrazione viene ripristinata senza la necessità di scrivere un metodo down separato".
Vedere " Migrazioni di record attivi " per ulteriori informazioni.
rails g migration FixColumnName
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Se ti capita di avere un sacco di colonne da rinominare, o qualcosa che avrebbe richiesto la ripetizione ripetuta del nome della tabella:
rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...
Puoi usare change_table
per mantenere le cose un po 'più ordinate:
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
Quindi db:migrate
come al solito o comunque fai i tuoi affari.
Per Rails 4:
Durante la creazione di a Migration
per rinominare una colonna, Rails 4 genera un change
metodo anziché up
e down
come indicato nella sezione precedente. Il change
metodo generato è:
$ > rails g migration ChangeColumnName
che creerà un file di migrazione simile a:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
self.up
non direi self.down
"dovrei sempre essere contrario". In dipende dal contesto della migrazione. Mettere il "contrario" potrebbe non essere la "giusta" down migrazione.
def self.up
e def self.down
con def change
e saprà eseguire il rollback.
change
metodo non sia una prova completa, quindi tendo a usare up
e down
metodi per migrazioni complesse.
A mio avviso, in questo caso, è meglio usare rake db:rollback
, quindi modificare la migrazione ed eseguire nuovamente rake db:migrate
.
Tuttavia, se nella colonna sono presenti dati che non si desidera perdere, utilizzare rename_column
.
Se la colonna è già popolata con dati e vive in produzione, consiglierei un approccio graduale, in modo da evitare tempi di inattività nella produzione in attesa delle migrazioni.
Innanzitutto creerei una migrazione db per aggiungere colonne con i nuovi nomi e popolarli con i valori dal vecchio nome di 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
Quindi commetterei proprio quel cambiamento e spingerei il cambiamento in produzione.
git commit -m 'adding columns with correct name'
Quindi, una volta che il commit è stato messo in produzione, corro.
Production $ bundle exec rake db:migrate
Quindi aggiornerei tutte le viste / i controller che facevano riferimento al vecchio nome di colonna al nuovo nome di colonna. Esegui la mia suite di test e apporta solo quelle modifiche. (Dopo essersi accertato che funzionasse localmente e prima avesse superato tutti i test!)
git commit -m 'using correct column name instead of old stinky bad column name'
Quindi spingerei questo impegno nella produzione.
A questo punto puoi rimuovere la colonna originale senza preoccuparti di alcun tipo di downtime associato 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 quest'ultima migrazione verso la produzione ed eseguirla bundle exec rake db:migrate
in background.
Mi rendo conto che questo è un po 'più coinvolto in un processo, ma preferirei farlo piuttosto che avere problemi con la mia migrazione di produzione.
execute "Update table_name set correct_name_column_one = old_name_column_one"
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.
rename_column
.
Esegui il comando seguente per creare un file di migrazione:
rails g migration ChangeHasedPasswordToHashedPassword
Quindi nel file generato nella db/migrate
cartella, scrivi rename_column
come di seguito:
class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Alcune versioni di Ruby on Rails supportano il metodo su / giù per la migrazione e se hai un metodo su / giù nella tua 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 hai il change
metodo nella tua 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 migrazioni di record attivi .
Se il tuo codice non è condiviso con un altro, l'opzione migliore è fare semplicemente rake db:rollback
modificare il nome della colonna durante la migrazione e rake db:migrate
. Questo è tutto
E puoi scrivere un'altra migrazione per rinominare la colonna
def change
rename_column :table_name, :old_name, :new_name
end
Questo è tutto.
rake db:rollback
è un ottimo suggerimento. Ma come hai detto, solo se la migrazione non è stata ancora spinta.
In alternativa, se non sei sposato con l'idea delle migrazioni, esiste una gemma avvincente per ActiveRecord che gestirà automaticamente le modifiche del nome, stile Datamapper. Tutto quello che fai è cambiare il nome della colonna nel tuo modello (e assicurati di mettere Model.auto_upgrade! Nella parte inferiore del tuo modello.rb) e viola! Il database viene aggiornato al volo.
https://github.com/DAddYE/mini_record
Nota: è necessario eseguire il nuke di db / schema.rb per prevenire conflitti
Ancora in fase beta e ovviamente non per tutti ma comunque una scelta convincente (lo sto attualmente utilizzando in due app di produzione non banali senza problemi)
Se è necessario cambiare i nomi delle colonne, sarà necessario creare un segnaposto per evitare un errore di nome della colonna duplicato . 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
Se i dati attuali non sono importanti per te, puoi semplicemente annullare la migrazione originale usando:
rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'
Senza le virgolette, quindi apportare modifiche alla migrazione originale ed eseguire nuovamente la migrazione verso l'alto:
rake db:migrate
Per Ruby on Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
Manualmente possiamo usare il metodo seguente:
Possiamo modificare manualmente la migrazione come:
Aperto app/db/migrate/xxxxxxxxx_migration_file.rb
Aggiorna hased_password
ahashed_password
Esegui il comando seguente
$> rake db:migrate:down VERSION=xxxxxxxxx
Quindi rimuoverà la migrazione:
$> rake db:migrate:up VERSION=xxxxxxxxx
Aggiungerà la tua migrazione con la modifica aggiornata.
Esegui rails g migration ChangesNameInUsers
(o come vuoi nominarlo)
Apri il file di migrazione che è stato appena generato e aggiungi 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 eseguirlo rake db:migrate
nella console
Controlla il tuo schema.db
per vedere se il nome è stato effettivamente modificato nel database!
Spero che sia di aiuto :)
Facciamo BACIO . Bastano tre semplici passaggi. Quanto segue funziona per Rails 5.2 .
rails g migration RenameNameToFullNameInStudents
rails g RenameOldFieldToNewFieldInTableName
- in questo modo è perfettamente chiaro ai manutentori della base di codice in seguito. (usa un plurale per il nome della tabella).
# I prefer to explicitly write the
su and
giùmethods.
# ./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
rake db:migrate
E sei partito per le gare!
$: rails g migration RenameHashedPasswordColumn
invoke active_record
create db/migrate/20160323054656_rename_hashed_password_column.rb
Apri quel file di migrazione e modifica quel file come di seguito (inserisci il tuo originale table_name
)
class RenameHashedPasswordColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Apri la tua console Ruby on Rails ed inserisci:
ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
Hai due modi per farlo:
In questo tipo, esegue automaticamente il codice inverso, al momento del rollback.
def change
rename_column :table_name, :old_column_name, :new_column_name
end
Per questo tipo, esegue il metodo up quando rake db:migrate
e il metodo down quando rake 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 sto provando a rinominare una colonna su un utente ideato.
il rename_column
bit ha funzionato per me, ma il singolare :table_name
ha generato un errore "Tabella utente non trovata". Plural ha funzionato per me.
rails g RenameAgentinUser
Quindi modificare il file di migrazione in questo:
rename_column :users, :agent?, :agent
Dove: agente? è il vecchio nome della colonna.
Aggiornamento - Un cugino stretto di create_table è change_table, utilizzato per modificare le tabelle esistenti. Viene usato in modo simile a create_table ma l'oggetto ceduto al blocco conosce più trucchi. Per 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ù efficiente se lo facciamo con altri metodi di modifica come: rimuovi / aggiungi indice / rimuovi indice / aggiungi colonna, ad esempio possiamo fare ulteriormente 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
#...
Basta generare la migrazione usando il comando
rails g migration rename_hased_password
Dopo aver modificato la migrazione, aggiungere la seguente riga nel metodo change
rename_column :table, :hased_password, :hashed_password
Questo dovrebbe fare il trucco.
Rails 5 modifiche alla migrazione
per esempio:
rotaie g modello Student nome_ studente: stringa età: intero
se vuoi cambiare la colonna student_name come nome
Nota: - se non si esegue rails db: migrate
Puoi fare i seguenti passi
rotaie modello Student nome_ studente: stringa età: intero
Questo rimuoverà il file di migrazione generato, Ora puoi correggere il nome della tua colonna
rotaie modello g Nome dello studente: stringa età: intero
Se è stata eseguita la migrazione (rails db: migrate), seguire le opzioni per modificare il nome della colonna
rails g migrazione RemoveStudentNameFromStudent nome_ studente: stringa
rotaie g AddNameToStudent nome: stringa
rails g migration RemoveStudentNameFromStudentS student_name:string
(gli studenti sono plurali)?