Ruby on Rails: Jak dodać ograniczenie niezerowe do istniejącej kolumny przy użyciu migracji?

135

W mojej aplikacji Rails (3.2) mam kilka tabel w mojej bazie danych, ale zapomniałem dodać kilka nie zerowych ograniczeń. Przeszukałem go, ale nie mogę znaleźć sposobu na napisanie migracji, która dodaje wartość niezerową do istniejącej kolumny.

TIA.

David Robertson
źródło

Odpowiedzi:

94

Dla Rails 4+, odpowiedź natesa (używając change_column_null ) jest lepsza.

Pre-Rails 4, spróbuj change_column .

Dan Wich
źródło
26
Uważaj przy tym podejściu - jeśli masz inne atrybuty dotyczące tej kolumny (na przykład :limitograniczenie), musisz powtórzyć te atrybuty podczas używania change_column, w przeciwnym razie zostaną utracone. Z tego powodu wolę używaćchange_column_null
Nathan Wallace
Zauważ, że generuje to, IrreversibleMigrationco może nie być tym, czego chcesz.
Nic Nilov,
@NicNilov, czy mówisz o odpowiedzi czy komentarzu Nathana Wallace'a?
Mark
@Mark Mówiłem o odpowiedzi, przepraszam, że nie jest wystarczająco konkretna.
Nic Nilov
@NicNilov no dw Pomyślałem, że chociaż chciałem tylko dokładnie sprawdzić :)
Mark
280

Możesz również użyć change_column_null :

change_column_null :table_name, :column_name, false
nates
źródło
8
Najczystsza odpowiedź!
Josh Click
1
Musiałem to zmienić dla kilku kolumn i nie wymaga to określania typu kolumny dla każdej kolumny, znacznie lepiej!
Dorian
1
To jest lepsza odpowiedź. W mojej bazie danych dodawałem ograniczenie zerowe do kolumny z wcześniej istniejącymi wartościami null. change_column nie zaktualizuje tych wartości. Zgodnie z dokumentacją change_column_null ma opcjonalną czwartą wartość, która jest nową wartością aktualizacji.
Merovex
Dzięki za to. Najlepsza odpowiedź.
Ryan Rebo,
1
ciekawy efekt uboczny… cofnięcie migracji spowoduje ustawienie pola na przeciwne (fałsz -> prawda). Więc jeśli utworzysz migrację dla kilku pól, aby dodać ograniczenie zerowe, a niektóre pola JUŻ miały ograniczenie zerowe, a następnie wycofaj migrację, USUŃ to ograniczenie zerowe z dowolnego pola, które już je miało.
jpw
11

1) PIERWSZA: Dodaj kolumnę z wartością domyślną

2) TO: Usuń wartość domyślną

add_column :orders, :items, :integer, null: false, default: 0
change_column :orders, :items, :integer, default: nil
rndrfero
źródło
2
jest to poprawne rozwiązanie, gdy chcesz dodać nową kolumnę, która nie jest pusta, musisz najpierw zdefiniować, że ma ona wartość domyślną, ponieważ SQLLite będzie narzekać (nie można dodać kolumny NOT NULL z wartością domyślną NULL), a następnie ją usunąć!
Mediolan
3

Jeśli używasz go w nowym skrypcie / schemacie tworzenia migracji, tutaj możemy go zdefiniować

class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
    t.string :name, null: false     # Notice here, NOT NULL definition
    t.string :email, null: false
    t.string :password, null: false
    t.integer :created_by
    t.integer :updated_by 

    t.datetime :created_at
    t.datetime :updated_at, default: -> { 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' }
   end
  end
end
Manjunath Reddy
źródło