Jak zmienić nazwę kolumny bazy danych w Ruby on Rails migration?

Błędnie nazwałem kolumnę hased_password zamiast hashed_password.

Jak zaktualizować schemat bazy danych, używając migracji do zmiany nazwy tej kolumny?

Author: Peter Mortensen, 2010-01-02

25 answers

rename_column :table, :old_column, :new_column

Update:

Prawdopodobnie będziesz chciał utworzyć oddzielną migrację, aby to zrobić. (Zmień nazwę FixColumnName jak chcesz)

script/generate migration FixColumnName
# creates  db/migrate/xxxxxxxxxx_fix_column_name.rb

Następnie Edytuj migrację, aby wykonać swoją wolę.

# 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

Aktualizacja dla Rails 3.1

While, metody up i down nadal obowiązują. Rails 3.1 otrzymuje metodę change, która "wie, jak przenieść bazę danych i odwrócić ją, gdy migracja jest cofnięta, bez konieczności pisania separate down method "

rails g migration FixColumnName

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

Jeśli zdarzy ci się mieć całą masę kolumn do zmiany nazwy lub coś, co wymagałoby powtarzania nazwy tabeli w kółko.

rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...
Mógłbyś użyć change_table, żeby zachować porządek.
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

Dziękuję., Luke && Turadg, za poruszenie tematu.

Potem po prostu db:migrate Jak zwykle lub jak chcesz zająć się swoimi sprawami.


Aktualizacja dla Rails 4

Rails 4 generuje metodę change zamiast up i down, Jak wspomniano w powyższej odpowiedzi. Wygenerowana metoda change jest jak poniżej:
$ > rails g migration ChangeColumnName

Który utworzy plik migracji podobny do tego:

class ChangeColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
 2115
Author: nowk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 19:18:33

IMO, w tym przypadku lepiej używać rake db:rollback. Następnie Edytuj migrację i ponownie wpisz rake db:migrate. Jeśli jednak masz dane w kolumnie, której nie chcesz stracić, użyj rename_column.

 66
Author: elf.xf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 21:51:09

Http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Pod Available Transformations

rename_column(table_name, column_name, new_column_name):

Zmienia nazwę kolumny, ale zachowuje typ i zawartość.

 26
Author: James Manning,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-07 11:34:54

Jeśli kolumna jest już wypełniona danymi i działa w produkcji, polecam podejście krok po kroku, aby uniknąć przestojów w produkcji podczas oczekiwania na migracje.

Najpierw utworzyłbym migrację db, aby dodać kolumny o nowej nazwie i wypełnić je wartościami ze starej nazwy kolumny.

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

Wtedy dokonałbym tylko tej zmiany, i pchnąłbym zmiany do produkcji.

git commit -m 'adding columns with correct name'

Wtedy gdy commit zostanie wprowadzony do produkcji, uciekaj.

Production $ bundle exec rake db:migrate

Następnie zaktualizowałbym wszystkie widoki/kontrolery, które odwołują się do starej nazwy kolumny do nowej nazwy kolumny. Przejrzyj mój zestaw testów i zatwierdź tylko te zmiany. (Po upewnieniu się, że działa lokalnie i zaliczeniu wszystkich testów w pierwszej kolejności!)

git commit -m 'using correct column name instead of old stinky bad column name'
Wtedy wcisnąłbym to zobowiązanie do produkcji.

W tym momencie możesz usunąć oryginalną kolumnę bez obawy o jakiekolwiek przestoje związane z samą migracją.

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

Następnie naciśnij to ostatnia migracja do produkcji i uruchomić bundle exec rake db:migrate w tle.

Zdaję sobie sprawę, że jest to trochę bardziej związane z procesem, ale wolę to zrobić, niż mieć problemy z moją migracją produkcji.

 24
Author: Paul Pettengill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-14 02:01:38

Uruchom poniższe polecenie, aby utworzyć plik migracji:

rails g migration ChangeHasedPasswordToHashedPassword

Następnie w pliku wygenerowanym w folderze db/migrate napisz {[3] } Jak poniżej:

class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
  def change
     rename_column :table_name, :hased_password, :hashed_password
  end
end
 16
Author: Shoaib Malik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 21:56:42

Z API:

rename_column(table_name, column_name, new_column_name)

Zmienia nazwę kolumny, ale zachowuje typ i zawartość.

 13
Author: super_p,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-10 13:01:24

Niektóre wersje Ruby on Rails obsługują metodę up/down do migracji, a jeśli masz metodę up/down w swojej migracji, to:

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

Jeśli masz metodę change w swojej migracji, to:

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

Aby uzyskać więcej informacji, możesz przenieść: Ruby on Rails-migracje lub migracje rekordów aktywnych.

 12
Author: uma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 21:54:00

Jeśli Twój kod nie jest współdzielony z innym, najlepszym rozwiązaniem jest zrobienie tylko rake db:rollback następnie Edytuj nazwę kolumny w migration i rake db:migrate. Thats it

I możesz napisać kolejną migrację, aby zmienić nazwę kolumny

 def change
    rename_column :table_name, :old_name, :new_name
  end
To wszystko.
 10
Author: sunil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-04 14:34:30

Jeśli chcesz zmienić nazwy kolumn, musisz utworzyć symbol zastępczy, aby uniknąć błędu duplikatu nazwy kolumny . Oto przykład:

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
 8
Author: Abram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-09 14:25:51

Jako alternatywna opcja, jeśli nie jesteś żonaty z ideą migracji, istnieje atrakcyjny klejnot dla ActiveRecord, który obsłuży zmiany nazw automatycznie dla Ciebie, Datamapper style. Wszystko, co robisz, to zmieniasz nazwę kolumny w swoim modelu (i upewnij się, że umieściłeś model .auto_upgrade!Na dole Twojego modelu.rb) i viola! Baza danych jest aktualizowana w locie.

Https://github.com/DAddYE/mini_record

Uwaga: trzeba będzie nuke db / schema.RB aby zapobiec konfliktom

Wciąż w fazie beta i oczywiście nie dla wszystkich, ale wciąż atrakcyjny wybór (obecnie używam go w dwóch nietrywialnych aplikacjach produkcyjnych bez problemów)

 7
Author: Steven Garcia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-12 13:57:26

Jeśli obecne dane nie są dla Ciebie ważne, możesz po prostu usunąć oryginalną migrację za pomocą:

rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'

Bez cudzysłowów, następnie wprowadź zmiany w oryginalnej migracji i uruchom migrację ponownie przez:

rake db:migrate
 6
Author: dirtydexter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 21:51:47

Po prostu utwórz nową migrację, a w bloku użyj rename_column Jak Poniżej.

rename_column :your_table_name, :hased_password, :hashed_password
 6
Author: jon snow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 21:55:06

Dla Ruby on Rails 4:

def change
    rename_column :table_name, :column_name_old, :column_name_new
end
 6
Author: Hardik Hardiya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 21:57:01

Ręcznie możemy użyć poniższej metody:

Możemy ręcznie edytować migrację w następujący sposób:

  • Open app/db/migrate/xxxxxxxxx_migration_file.rb

  • Update hased_password to hashed_password

  • Uruchom poniższe polecenie

    $> rake db:migrate:down VERSION=xxxxxxxxx
    

Wtedy usunie Twoją migrację:

$> rake db:migrate:up VERSION=xxxxxxxxx

Doda Twoją migrację wraz ze zaktualizowaną zmianą.

 5
Author: Sumit Munot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 21:56:04

Wygenerowanie pliku migracji:

rails g migration FixName

# tworzy db / migrate / xxxxxxxxx.rb

Edytuj migrację, aby wykonać swoją wolę.

class FixName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
 4
Author: vipin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 21:59:36
$:  rails g migration RenameHashedPasswordColumn
invoke  active_record
      create    db/migrate/20160323054656_rename_hashed_password_column.rb

Otwórz ten plik migracji i zmodyfikuj go jak poniżej (Wprowadź swój oryginalny table_name)

class  RenameHashedPasswordColumn < ActiveRecord::Migration
  def change
    rename_column :table_name, :hased_password, :hashed_password
  end
end
 4
Author: Prabhakar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-23 05:49:28

Run rails g migration ChangesNameInUsers (czy jak chcesz to nazwać)

Otwórz plik migracji, który został właśnie wygenerowany, i dodaj tę linię w metodzie (pomiędzy def change i end):

rename_column :table_name, :the_name_you_want_to_change, :the_new_name

Zapisz plik i uruchom rake db:migrate w konsoli

Sprawdź swoją schema.db, aby sprawdzić, czy nazwa rzeczywiście zmieniła się w bazie danych!

Mam nadzieję, że to pomoże:)

 4
Author: Maddie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-23 16:10:36

Generowanie migracji Ruby on Rails :

$:> rails g migration Fixcolumnname

Wstaw kod w pliku migracji (XXXXXfixcolumnname.rb):

class Fixcolumnname < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
 3
Author: vipin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 22:00:14
 def change
    rename_column :table_name, :old_column_name, :new_column_name
  end
 3
Author: Apoorv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-08 18:01:21

Otwórz konsolę Ruby on Rails i wpisz:

ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
 2
Author: rinold simon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 21:58:51

Masz na to dwa sposoby:

  1. W tym typie automatycznie uruchamia jego kod odwrotny, po wycofaniu.

    def change
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
  2. Do tego typu, uruchamia metodę up when rake db:migrate i uruchamia metodę down when 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
    
 2
Author: Sarwan Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-05 05:10:58

Jestem na rails 5.2 i próbuję zmienić nazwę kolumny na użytkowniku devise.

Bit rename_column zadziałał dla mnie, ale pojedynczy :table_name wyrzucił błąd "User table not found". Liczba mnoga mi pomogła.

rails g RenameAgentinUser

Następnie zmień plik migracji na ten:

rename_column :users, :agent?, :agent

Gdzie :agent? to stara nazwa kolumny.

 1
Author: tomb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-06 13:42:53

Wystarczy wygenerować migrację za pomocą polecenia

rails g migration rename_hased_password

Po tej edycji migracji Dodaj następujący wiersz w metodzie Zmień

rename_column :table, :hased_password, :hashed_password
To powinno załatwić sprawę.
 0
Author: Ratnam Yadav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-05 12:02:57

Rails 5 migration changes

Eg:

Rails g Model Student student_name: string age: integer

Jeśli chcesz zmienićstudent_name column jako name

Note: - if you not run rails db: migrate

Możesz wykonać następujące kroki

Rails d Model Student student_name: string age: integer

Spowoduje to usunięcie wygenerowanego pliku migracji, teraz możesz poprawić nazwę kolumny

Rails g model Student name: string age: integer

W przypadku migracji (rails db: migrate), następujące opcje zmiany nazwy kolumny

Rails g migration RemoveStudentNameFromStudent student_name: string

Rails g migration AddNameToStudent name: string

 0
Author: prasanthrubyist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-20 12:08:30

Update - bliskim kuzynem create_table jest change_table, używany do zmiany istniejących tabel. Jest on używany w podobny sposób jak create_table, ale obiekt poddany blokowi zna więcej sztuczek. Na przykład:

class ChangeBadColumnNames < ActiveRecord::Migration
  def change
    change_table :your_table_name do |t|
      t.rename :old_column_name, :new_column_name
    end
  end
end

Ten sposób jest bardziej efektywny, jeśli robimy z innymi metodami alter takimi jak: remove / add index/remove index / add column, np. możemy zrobić dalej jak:

# 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
#...
 -1
Author: Hieu Pham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-21 05:32:00