W poprzedniej migracji utworzyłem kolumnę daty i ustawiłem ją na wartość null. Teraz chcę to zmienić, aby nie było zerowalne. Jak mam to zrobić, zakładając, że w tej bazie danych są puste wiersze? Nie przeszkadza mi ustawienie tych kolumn na Time.now, jeśli obecnie są one puste.
ruby-on-rails
migration
Kevin Pang
źródło
źródło
MyModel.update_all({:date_column => Time.now}, {:date_column => nil})
. Zapytanie w oryginalnej formie właśnie sprawiło, że wszystkie moje modele mają zero wartości w polu.change
Metoda nie jest tak nadaje się do tej sprawy, ponieważ (1)update_all
metoda będzie realizowane zarówno na migrować i potencjalnego Przywróć. To może nie być najgorsze, ale ponieważ (2) migracja nie ma możliwości dowiedzenia się, z czego zmieniono kolumnę w potencjalnym przywróceniu. Więc w tym przypadku trzymałbym sięup
idown
.W Rails 4 jest to lepsze (DRYer) rozwiązanie:
Aby upewnić się, że nie ma żadnych rekordów z
NULL
wartościami w tej kolumnie, możesz przekazać czwarty parametr, który jest wartością domyślną używaną dla rekordów zNULL
wartościami:źródło
change_column_null
. Jednak powyższy komentarz Ricka Smitha wskazuje na bardzo ważny przypadek.Railsy 4 (inne odpowiedzi na Railsy 4 mają problemy):
Zmiana kolumny z wartościami NULL, aby nie zezwalać na NULL, spowoduje problemy. Jest to dokładnie ten rodzaj kodu, który będzie działał dobrze w konfiguracji programistycznej, a następnie zawiesi się, gdy spróbujesz wdrożyć go do produkcji LIVE . Najpierw powinieneś zmienić wartości NULL na coś prawidłowego, a następnie zabronić wartości NULL. Czwarta wartość w
change_column_null
dokładnie to robi. Więcej informacji znajduje się w dokumentacji .Ponadto ogólnie wolę ustawić wartość domyślną dla pola, więc nie będę musiał określać wartości pola za każdym razem, gdy tworzę nowy obiekt. Dołączyłem również skomentowany kod, aby to zrobić.
źródło
add_column :users, :admin, :string
a następniechange_column_null(:admin, :string, false, "new_value_for_existing_records")
Utwórz migrację, która ma
change_column
instrukcję z:default =>
wartością.Zobacz: change_column
W zależności od silnika bazy danych może być konieczne użycie
change_column_null
źródło
change_column_null
.Szyny 4:
źródło
W Railsach 4.02+ zgodnie z dokumentacją nie ma metody podobnej
update_all
do 2 argumentów. Zamiast tego można użyć tego kodu:źródło
Nie możesz używać add_timestamps i null: false, jeśli masz istniejące rekordy, więc oto rozwiązanie:
źródło