Додавання: за замовчуванням => вірно булевим у існуючому стовпці Rails


160

Я бачив кілька запитань (а саме цього ) тут на SO про додавання бульового значення за замовчуванням до наявного стовпця. Тому я спробував change_columnпропозицію, але я не повинен робити це правильно.

Я намагався:

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

Який повертається -bash: change_column: command not found

Я тоді побіг:

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

... і

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

Потім побіг rake db:migrate, але значення для :show_attributeзалишилося nil. У питанні, на яке я посилався вище, в PostgreSQL сказано, що вам потрібно оновити його вручну. Оскільки я використовую PostgreSQL, я додав наступне під час create_profilesміграції:

t.boolean :show_attribute, :default => true

Може хтось скаже мені, що я тут роблю неправильно?

Відповіді:


314

change_columnце метод ActiveRecord::Migration, тому ви не можете його так називати в консолі.

Якщо ви хочете додати до цього стовпця значення за замовчуванням, створіть нову міграцію:

rails g migration add_default_value_to_show_attribute

Потім у міграції створено:

# 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

АБО більш конкретний варіант:

def up
    change_column_default :profiles, :show_attribute, true
end

def down
    change_column_default :profiles, :show_attribute, nil
end

Потім бігайте rake db:migrate.

Це нічого не змінить до вже створених записів. Для цього вам доведеться створити rake taskабо просто зайти в rails consoleта оновити всі записи (що я не рекомендував би у виробництві).

Коли ви додасте t.boolean :show_attribute, :default => trueдо create_profilesміграції, очікується, що вона нічого не зробить. Виконуються лише міграції, які ще не були виконані. Якщо ви почали зі свіжої бази даних, то вона встановила б за замовчуванням значення true.


2
Цей виклик change_column має бути в upметоді міграції, який є новим класом, який буде сформований у db / migrate /. ( downМетод повинен бути записаний, щоб скасувати, що upробить.) Потім внесіть ці зміни rake db:migrate.
rkb

Ах, це має більше сенсу rkb. Дякую!
tvalent2

це не працювало для мене, поки я не написав def self.upіdef self.down
Каміль Шот

Ви, мабуть, тоді використовували більш стару версію рейок. Я думаю, що цей синтаксис існує з 3.1.
Робін

І в Rails 5 ви відмовляєтеся від _attribute, так що він повинен просто сказати showабо як би це не було.
лабіринт

95

Як варіант щодо прийнятої відповіді, ви також можете використовувати change_column_defaultметод під час міграцій:

def up
  change_column_default :profiles, :show_attribute, true
end

def down
  change_column_default :profiles, :show_attribute, nil
end

API-документи Rails


1
Це гарантує, що ви випадково не зміните жодної з інших властивостей стовпця
Брайан

1
І в Rails 5 ви відмовляєтеся від _attribute, так що він повинен просто сказати showабо як би це не було.
лабіринт

1
@labyrinth Що ти маєш на увазі? show_attribute це назва стовпця, я не думаю, що рейки 5 не мають нічого спільного з цим, правда?
Робін

34

Я не впевнений, коли це було написано, але наразі для додавання чи видалення за замовчуванням зі стовпця під час міграції ви можете використовувати наступне:

change_column_null :products, :name, false

Рейки 5:

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

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

Рейки 4.2:

change_column_default :products, :approved, false

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

Це акуратний спосіб уникнути перегляду міграцій чи схем для специфікацій стовпців.


Обережно, це з документації Rails 5. Версія для Rails 4.2 не приймає хеш, а абсолютно новий за замовчуванням як третій параметр. guides.rubyonrails.org/v4.2/…
Clamoris

Щодо Rails 5, то робити обидва, мабуть, найбільш правильний спосіб, наприклад, null: falseі в default: :somethingосновному
Доріан

1

Також відповідно до документа:

за замовчуванням не можна вказати через командний рядок

https://guides.rubyonrails.org/active_record_migrations.html

Так що немає готового генератора рейок. Як зазначено вище, відповіді вам потрібно вручну заповнити міграційний файл change_column_defaultметодом.

Ви можете створити власний генератор: https://guides.rubyonrails.org/generators.html


1

Якщо ви щойно здійснили міграцію, ви зможете відкатати і знову зробити міграцію.

Для відкату ви можете зробити скільки завгодно кроків:

rake db:rollback STEP=1

Або якщо ви використовуєте Rails 5.2 або новішу версію:

rails db:rollback STEP=1

Потім ви можете просто зробити міграцію знову:

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

Не забувайте rake db:migrateі якщо ви використовуєте herokuheroku run rake db:migrate


0
change_column :things, :price_1, :integer, default: 123, null: false

Здається, найкращим способом додати за замовчуванням до існуючого стовпця, який не має null: false .

Інакше:

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

Деякі дослідження, які я зробив з цього приводу:

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


0

Якщо ви не хочете створити інший файл міграції для невеликої, недавньої зміни - з консолі Rails:

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

Потім вийдіть і повторно введіть консоль рейли, так що зміни DB-B будуть чинними. Потім, якщо ви це зробите ...

Profile.new()

Ви повинні побачити значення "default_attribute" за замовчуванням як істинне.

Для існуючих записів, якщо ви хочете зберегти існуючі "помилкові" налаштування та оновити лише значення "нуль" до нового за замовчуванням:

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

Оновіть міграцію, що створила цю таблицю, щоб будь-яка майбутня збірка БД отримала її з самого початку. Також запустіть той самий процес на будь-яких розгорнутих екземплярах БД.

Якщо використовується метод "нової міграції db", ви можете виконати оновлення існуючих нульових значень у цій міграції.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.