migrations Come posso rinominare una colonna del database in una migrazione Ruby on Rails?




ruby on rails migrations (20)

Ho erroneamente chiamato una colonna hased_password anziché hashed_password .

Come aggiorno lo schema del database, usando la migrazione per rinominare questa colonna?


IMO, in questo caso, usa meglio rake db:rollback . Quindi modifica la tua migrazione e digita nuovamente rake db:migrate . Tuttavia, se hai dati nella colonna che non vuoi perdere, usa rename_column .


Basta generare la migrazione usando il comando

rails g migration rename_hased_password

Dopo tale modifica, la migrazione aggiunge la seguente riga nel metodo di modifica

rename_column :table, :hased_password, :hashed_password

Questo dovrebbe fare il trucco.



Esegui il comando seguente per creare un file di migrazione:

rails g migration ChangeHasedPasswordToHashedPassword

Quindi nel file generato nella cartella db/migrate , scrivi rename_column come di seguito:

class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
  def change
     rename_column :table_name, :hased_password, :hashed_password
  end
end

Genera una migrazione Ruby on Rails :

$:> rails g migration Fixcolumnname

Inserisci il codice nel file di migrazione (XXXXXfixcolumnname.rb) :

class Fixcolumnname < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

$:  rails g migration RenameHashedPasswordColumn
invoke  active_record
      create    db/migrate/20160323054656_rename_hashed_password_column.rb

Apri quel file di migrazione e modifica il file come sotto (Inserisci il nome della tabella originale)

class  RenameHashedPasswordColumn < ActiveRecord::Migration
  def change
    rename_column :table_name, :hased_password, :hashed_password
  end
end

Se la colonna è già popolata con dati e vivi in ​​produzione, ti consiglio un approccio graduale, in modo da evitare tempi di inattività durante l'attesa delle migrazioni.

Innanzitutto vorrei creare una migrazione db per aggiungere colonne con i nuovi nomi e popolarli 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 impegnerei proprio in quel cambiamento e spingere il cambiamento in produzione.

git commit -m 'adding columns with correct name'

Quindi, una volta che il commit è stato spinto in produzione, correrei.

Production $ bundle exec rake db:migrate

Quindi aggiornerei tutte le viste / i controller che facevano riferimento al nome della vecchia colonna al nuovo nome della colonna. Esegui la mia suite di test e commetti solo tali modifiche. (Dopo aver verificato che funzionasse localmente e superando prima tutti i test!)

git commit -m 'using correct column name instead of old stinky bad column name'

Quindi spingere l'impegno alla produzione.

A questo punto è possibile rimuovere la colonna originale senza preoccuparsi 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 questa ultima migrazione alla produzione ed eseguire bundle exec rake db:migrate in background.

Mi rendo conto che questo è un po 'più impegnativo di un processo, ma preferirei farlo piuttosto che avere problemi con la mia migrazione di produzione.


Come opzione alternativa, se non sei sposato con l'idea delle migrazioni, c'è una gemma avvincente per ActiveRecord che gestirà automaticamente le modifiche al nome per te, in stile Datamapper. Tutto quello che fai è cambiare il nome della colonna nel tuo modello (e assicurati di aver installato Model.auto_upgrade! Nella parte inferiore del tuo model.rb) e viola! Il database è aggiornato al volo.

https://github.com/DAddYE/mini_record

Nota: sarà necessario nuke db / schema.rb per evitare conflitti

Ancora in fase beta e ovviamente non per tutti ma ancora una scelta irresistibile (attualmente la sto utilizzando in due app di produzione non banali senza problemi)


Esegui rails g migration ChangesNameInUsers (o qualsiasi altra cosa desideri nominare)

Apri il file di migrazione che è appena stato generato e aggiungi questa linea nel metodo (tra la def change e la end ):

rename_column :table_name, :the_name_you_want_to_change, :the_new_name

Salva il file ed esegui rake db:migrate nella console

Controlla il tuo schema.db per vedere se il nome è effettivamente cambiato nel database!

Spero che questo ti aiuti :)


Rails 5 modifiche di migrazione

per esempio:

rails g model Studente student_name: string age: intero

se vuoi cambiare la colonna student_name come nome

Nota: - se non si esegue il comando rails db: migrate

Puoi fare i seguenti passi

rails d model Studente student_name: string age: intero

Questo rimuoverà il file di migrazione generato, Ora puoi correggere il nome della tua colonna

rails g model Nome dello studente: string age: intero

Se è stata eseguita la migrazione (rails db: migrate), le seguenti opzioni consentono di modificare il nome della colonna

rails g migration RemoveStudentNameFromStudent student_name: string

rails g migration AddNameToStudent name: string


Genera il file di migrazione:

rails g migration FixName

# Crea db / migrate / xxxxxxxxxx.rb

Modifica la migrazione per fare la tua volontà.

class FixName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

Alcune versioni di Ruby on Rails supportano il metodo up / down per la migrazione e se hai un metodo up / down 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 metodo di change nella tua migrazione, allora:

def change
    rename_column :table_name, :column_old_name, :column_new_name
end

Per ulteriori informazioni puoi muoverti: Ruby on Rails - Migrations o Active Record Migrations .


Se è necessario cambiare i nomi delle colonne, sarà necessario creare un segnaposto per evitare un errore del 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

Sono su Rails 5.2, e sto provando a rinominare una colonna su un utente devise.

il bit rename_column funzionato per me, ma il singolare :table_name ha generato un errore "User table not found". Il plurale ha funzionato per me

rails g RenameAgentinUser

Quindi modifica il file di migrazione con questo:

rename_column :users, :agent?, :agent

Dove: agente? è il nome della vecchia colonna.


Crea semplicemente una nuova migrazione e, in un blocco, utilizza rename_column come di seguito.

rename_column :your_table_name, :hased_password, :hashed_password

Apri la tua console Ruby on Rails e inserisci:

ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column

Aggiornamento : un cugino stretto di create_table è change_table, utilizzato per modificare le tabelle esistenti. È 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 utilizziamo altri metodi alternativi come: rimuovi / aggiungi indice / rimuovi indice / aggiungi colonna, ad esempio possiamo fare di più:

# 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
#...

Hai due modi per farlo:

  1. 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
    
  2. A questo tipo, esegue il metodo up quando rake db:migrate esegue la rake db:migrate e esegue 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
    

Per Ruby on Rails 4:

def change
    rename_column :table_name, :column_name_old, :column_name_new
end

 def change
    rename_column :table_name, :old_column_name, :new_column_name
  end




migration