Dodanie: default => true do wartości logicznej w istniejącej kolumnie Rails

160

Widziałem kilka pytań (a mianowicie to ) tutaj na SO o dodaniu domyślnej wartości boolowskiej do istniejącej kolumny. Więc wypróbowałem change_columnsugestię, ale nie mogę robić tego dobrze.

Próbowałem:

$ change_column :profiles, :show_attribute, :boolean, :default => true

Który powraca -bash: change_column: command not found

Następnie pobiegłem:

$ rails g change_column :profiles, :show_attribute, :boolean, :default => true

...i

$ rails change_column :profiles, :show_attribute, :boolean, :default => true

Następnie pobiegł rake db:migrate, ale wartość :show_attributepozostała nil. W pytaniu, do którego nawiązałem powyżej, jest napisane, że w PostgreSQL musisz zaktualizować go ręcznie. Ponieważ używam PostgreSQL, dodałem podczas create_profilesmigracji:

t.boolean :show_attribute, :default => true

Czy ktoś może mi powiedzieć, co tu robię źle?

tvalent2
źródło

Odpowiedzi:

314

change_columnjest metodą ActiveRecord::Migration, więc nie możesz jej tak nazywać w konsoli.

Jeśli chcesz dodać domyślną wartość dla tej kolumny, utwórz nową migrację:

rails g migration add_default_value_to_show_attribute

Następnie w migracji utworzono:

# That's the more generic way to change a column
def up
  change_column :profiles, :show_attribute, :boolean, default: true
end

def down
  change_column :profiles, :show_attribute, :boolean, default: nil
end

LUB bardziej szczegółowa opcja:

def up
    change_column_default :profiles, :show_attribute, true
end

def down
    change_column_default :profiles, :show_attribute, nil
end

Następnie biegnij rake db:migrate.

Nie zmieni to niczego w już utworzonych rekordach. Aby to zrobić, musisz utworzyć rake tasklub po prostu wejść do rails consolei zaktualizować wszystkie rekordy (czego nie polecałbym w produkcji).

Po dodaniu t.boolean :show_attribute, :default => truedo create_profilesmigracji oczekuje się, że nic nie zrobiło. Wykonywane są tylko migracje, które nie zostały jeszcze uruchomione. Jeśli zacząłeś od nowej bazy danych, ustawiłbyś wartość domyślną na true.

Rudzik
źródło
2
To wywołanie change_column powinno znajdować się w upmetodzie w migracji, która jest nową klasą, która zostanie wygenerowana w db / migrate /. ( downNależy napisać metodę, aby cofnąć to, co uprobi.) W takim razie wprowadź tę zmianę rake db:migrate.
rkb
Ahh, to ma więcej sensu rkb. Dzięki!
tvalent2
u mnie nie działało, dopóki nie napisałem def self.upidef self.down
Kamil Szot
Prawdopodobnie używasz wtedy starszej wersji szyn. Myślę, że ta składnia istnieje od 3.1.
Robin
A w Railsach 5 pomijasz atrybut _attribute, więc powinien po prostu mówić showlub cokolwiek to jest nazwa kolumny.
labirynt
95

Jako odmianę zaakceptowanej odpowiedzi możesz również użyć tej change_column_defaultmetody w swoich migracjach:

def up
  change_column_default :profiles, :show_attribute, true
end

def down
  change_column_default :profiles, :show_attribute, nil
end

Dokumentacja API Railsów

Sebastiaan Pouyet
źródło
1
Gwarantuje to, że przypadkowo nie zmienisz żadnych innych właściwości kolumny
Brian Low,
1
A w Railsach 5 pomijasz atrybut _attribute, więc powinien on po prostu powiedzieć, showczy jakakolwiek jest nazwa kolumny.
labirynt
1
@labyrinth Co masz na myśli? show_attribute to nazwa kolumny, nie sądzę, że rails 5 ma z tym coś wspólnego, prawda?
Robin
34

Nie jestem pewien, kiedy to zostało napisane, ale obecnie, aby dodać lub usunąć wartość domyślną z kolumny w migracji, możesz użyć następujących opcji:

change_column_null :products, :name, false

Szyny 5:

change_column_default :products, :approved, from: true, to: false

http://edgeguides.rubyonrails.org/active_record_migrations.html#changing-columns

Szyny 4.2:

change_column_default :products, :approved, false

http://guides.rubyonrails.org/v4.2/active_record_migrations.html#changing-columns

To zgrabny sposób na uniknięcie przeglądania migracji lub schematu specyfikacji kolumn.

fbelanger
źródło
Uwaga, pochodzi z dokumentacji Rails 5. Wersja Rails 4.2 tego nie akceptuje hasha, ale zupełnie nowy parametr domyślny jako trzeci parametr. guide.rubyonrails.org/v4.2/…
Clamoris
O Rails 5, czyniąc zarówno wydaje się być najbardziej właściwym sposobem, na przykład null: false, a default: :somethingprzede wszystkim
Dorian
1

Jeśli właśnie wykonałeś migrację, możesz ją wycofać, a następnie ponownie przeprowadzić migrację.

Aby przywrócić, możesz wykonać tyle kroków, ile chcesz:

rake db:rollback STEP=1

Lub, jeśli używasz Rails 5.2 lub nowszego:

rails db:rollback STEP=1

Następnie możesz po prostu ponownie przeprowadzić migrację:

def change
  add_column :profiles, :show_attribute, :boolean, default: true
end

Nie zapomnij rake db:migratei jeśli używasz herokuheroku run rake db:migrate

BM
źródło
0
change_column :things, :price_1, :integer, default: 123, null: false

Wydaje się, że jest to najlepszy sposób na dodanie wartości domyślnej do istniejącej kolumny, której jeszcze nie ma null: false.

Inaczej:

change_column :things, :price_1, :integer, default: 123

Kilka badań, które przeprowadziłem na ten temat:

https://gist.github.com/Dorian/417b9a0e1a4e09a558c39345d50c8c3b

dorycki
źródło
0

Jeśli nie chcesz tworzyć kolejnego pliku migracyjnego dla małej, niedawnej zmiany - z konsoli Rails:

ActiveRecord::Migration.change_column :profiles, :show_attribute, :boolean, :default => true

Następnie wyjdź i ponownie wejdź do konsoli rails, więc zmiany DB będą obowiązywać. Jeśli to zrobisz ...

Profile.new()

Powinieneś zobaczyć domyślną wartość „show_attribute” jako true.

W przypadku istniejących rekordów, jeśli chcesz zachować istniejące „fałszywe” ustawienia i zaktualizować tylko wartości „nil” do nowych wartości domyślnych:

Profile.all.each{|profile| profile.update_attributes(:show_attribute => (profile.show_attribute == nil ? true : false))  }

Zaktualizuj migrację, która utworzyła tę tabelę, aby wszystkie przyszłe kompilacje bazy danych otrzymały ją od samego początku. Uruchom również ten sam proces na wszystkich wdrożonych instancjach bazy danych.

Jeśli używasz metody „nowej migracji bazy danych”, możesz zaktualizować istniejące wartości zerowe w tej migracji.

JosephK
źródło