Zmień typ kolumny z Date na DateTime podczas migracji ROR

227

Muszę zmienić typ kolumny z daty na datę i godzinę dla tworzonej przeze mnie aplikacji. Nie dbam o dane, ponieważ wciąż są rozwijane.

W jaki sposób mogę to zrobić?

pies
źródło

Odpowiedzi:

508

Najpierw w twoim terminalu:

rails g migration change_date_format_in_my_table

Następnie w pliku migracji:

Dla szyn> = 3,2:

class ChangeDateFormatInMyTable < ActiveRecord::Migration
  def up
    change_column :my_table, :my_column, :datetime
  end

  def down
    change_column :my_table, :my_column, :date
  end
end
apneadiving
źródło
27
Masz rację, po prostu założyłem, że początkujący wybierze najnowszą dostępną technologię, ale to oczywiście nie jest pewne
apneadiving
12
Pytanie oznaczone jest jako „ruby-on-rails-3”
Sucrenoir,
2
@Sucrenoir Tak, tag został dodany przez nurkowanie po tym, jak odpowiedział.
Jason
10
Jeśli zastanawiasz się, dlaczego changenie zastosowano jednej metody zamiast metod upi down, to dlatego, że changemetoda nie obsługuje change_columndefinicji migracji .
Dennis
2
Ta odpowiedź jest tylko częściowo poprawna, nie możesz użyć zmiany_kolumny wewnątrz zmiany nawet na szynach 4 lub migracja w dół nie będzie działać. Powinieneś używać góra / dół bez względu na wersję szyn.
Alan Peabody
78

Ponadto, jeśli używasz Railsów 3 lub nowszych, nie musisz używać metod upi down. Możesz po prostu użyć change:

class ChangeFormatInMyTable < ActiveRecord::Migration
  def change
    change_column :my_table, :my_column, :my_new_type
  end
end
Lee McAlilly
źródło
78
Metoda zmiany działa tylko z odwracalnymi migracjami. Powyższy kod zgłosiłby wyjątek ActiveRecord :: IrreversibleMigration. W metodzie zmiany należy stosować tylko metody z api.rubyonrails.org/classes/ActiveRecord/Migration/… .
davekaro
3
Korzystam z Rails 4 i wcześniej przeprowadzałem taką migrację. ZMIANA NIE DZIAŁA! Komentarz @ davekaro jest poprawny.
harryt
3
W przypadku Rails 5 jest to prawidłowe i działające rozwiązanie.
WM
3
W przypadku odwrócenia skąd miałby wiedzieć, na jaki stary typ kolumny powinien wrócić?
Andrew Grimm
@AndrewGrimm masz rację. Oto, co widzę, gdy próbuję cofnąć migrację:This migration uses change_column, which is not automatically reversible. To make the migration reversible you can either: 1. Define #up and #down methods in place of the #change method. 2. Use the #reversible method to define reversible behavior.
Marklar,
42

W Railsach 3.2 i Railsach 4 popularna odpowiedź Benjamina ma nieco inną składnię.

Najpierw w twoim terminalu:

$ rails g migration change_date_format_in_my_table

Następnie w pliku migracji:

class ChangeDateFormatInMyTable < ActiveRecord::Migration
  def up
   change_column :my_table, :my_column, :datetime
  end

  def down
   change_column :my_table, :my_column, :date
  end
end
Thomas Klemm
źródło
23

Istnieje metoda change_column , po prostu uruchom ją podczas migracji z datetime jako nowy typ.

change_column(:my_table, :my_column, :my_new_type)
Nikita Rybak
źródło
1
czy to zachowuje oryginalne dane?
BKSpurgeon
1
Tak, zachowaj oryginalne dane
Mauro
1

AFAIK, migracje mają na celu przekształcenie danych, na których Ci zależy (tj. Produkcji) podczas wprowadzania zmian w schemacie. Więc jeśli nie jest to złe, a ponieważ powiedział, że nie dba o dane, dlaczego po prostu nie zmodyfikować typu kolumny w oryginalnej migracji z daty do daty i godziny i ponownie uruchomić migrację? (Mam nadzieję, że masz testy :)).

fakeleft
źródło
2
Możesz potencjalnie zainteresować się migracją w środowisku programistycznym, nawet jeśli nie dbasz o dane, jeśli pracujesz w zespole i chcesz, aby zmiana schematu rozprzestrzeniła się na wszystkich innych programistów w zespole.
Jose B
Mam problem z dostrzeżeniem korzyści, jakie daje dodatkowa migracja w celu zmiany kolumny w tej sytuacji. Co jest złego w zmianie oryginalnej migracji, która utworzyła kolumnę? W obu przypadkach każdy członek zespołu musi ponownie uruchomić wszystkie migracje, aby uzyskać nowy schemat.
fakeleft
Jeśli używasz nowej migracji, możesz po prostu cofnąć migrację, która zmieniła typ kolumny. Jeśli miałbyś edytować oryginał, musiałbyś cofnąć tę edycję i ponownie uruchomić migracje.
jazzpi
To właściwie bardzo rozważna odpowiedź, biorąc pod uwagę, że nie ma jeszcze danych produkcyjnych. Dla tych, którzy martwią się o innych członków zespołu, właśnie po to rake db:migrate:reset.
Ryan McGeary