Додайте значення за замовчуванням до стовпця за допомогою міграції


276

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

Вся документація, яку я можу знайти, показує вам, як це зробити, якщо стовпець уже не існує, але в цьому випадку він є.

Відповіді:


352

Ось як слід це зробити:

change_column :users, :admin, :boolean, :default => false

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


14
Якщо вам потрібні оборотні міграції, поставте це у upблок, а не в changeблок. Ви можете залишити downблок порожнім. Він не поверне таблицю до початкового стану, але міграцію можна повернути назад.
IAmNaN

1
Чи збереже це дані недоторканими?
Марко Прінс

2
На PostgreSQL так, я не знаю, що буде з іншими базами даних.
Маурісіо Лінхарес

1
Що ви маєте на увазі, коли говорите "переконайтеся, що ви оновили поле вручну під час міграції"? Як це зробити?
Девід Аргіле Такер

7
Я спробував це на PostgreSQL, і він оновив раніше створені поля.
Aboozar Rajabi

190
change_column_default :employees, :foreign, false

1
@DenisLins Я погодився з вами, тому я провів кілька досліджень, щоб з'ясувати, чому це не може бути, і виявляється, що існує можливість того, що певний адаптер бази даних не підтримує його, оскільки він реалізований на тому рівні. Прийнята відповідь як і раніше є найбезпечнішою ставкою, поки вона не буде реалізована в абстрактній моделі. apidock.com/rails/ActiveRecord/ConnectionAdapters/…
natchiketa

5
Крім того, вам потрібно вказати a, from:і to:якщо ви хочете, щоб він був зворотним :)
radubogdan

5
Використання fromта toдодавання до Rails 5+ у цьому комітеті
Джошуа Пінтер

115

Для Rails 4+ використовуйтеchange_column_default

def change
  change_column_default :table, :column, value
end

1
Це чудово, особливо якщо у вас є міграція, яка додає стовпець і встановлює параметри за замовчуванням для існуючих записів. Наприклад: def change `add_column: foos,: name, за замовчуванням:" щось для існуючих значень "` `change_column_default: foos,: name, default:" "`end
user1491929

2
Ця міграція має дивну поведінку. У вашому прикладі це незворотно. edgeguides.rubyonrails.org/active_record_migrations.html рекомендую використовувати його так: change_column_default :products, :approved, from: true, to: false- але це також не працює.
Ілля Кригузов

не можете відкатати за допомогою цього?
aldrien.h

Зазвичай так, майже для будь-якого пункту "Змінити", оскільки всі попередні стани зазвичай явні, такі як наявність стовпця, його тип тощо. Зміни можна повернути назад, як це показано там, і лише тоді, коли було чинний явний дефолт раніше. Оскільки звичайно, що значення за замовчуванням не визначено, у вас може виникнути проблема.
Еліндор

48

Використовуючи def changeзасоби, слід записувати зворотні міграції. І change_columnне є оборотним. Ви можете піти вгору, але не можете спуститися, оскільки change_columnце незворотно.

Натомість, хоч це може бути пара зайвих рядків, ви повинні використовувати def upіdef down

Отже, якщо у вас стовпець без значення за замовчуванням, то слід зробити це, щоб додати значення за замовчуванням.

def up
  change_column :users, :admin, :boolean, default: false
end

def down
  change_column :users, :admin, :boolean, default: nil
end

Або якщо ви хочете змінити значення за замовчуванням для існуючого стовпця.

def up
  change_column :users, :admin, :boolean, default: false
end

def down
  change_column :users, :admin, :boolean, default: true
end

37

** Рейки 4.X + **

Станом на Rails 4, ви не можете створити міграцію, щоб додати стовпець до таблиці зі значенням за замовчуванням . Наступні кроки додають новий стовпець до існуючої таблиці зі значенням за замовчуванням true або false.

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

$ rails generate migration add_columnname_to_tablename columnname:boolean

Наведена вище команда додасть новий стовпець у вашу таблицю.

2. Встановіть нове значення стовпця на TRUE / FALSE, відредагувавши створений новий файл міграції.

class AddColumnnameToTablename < ActiveRecord::Migration
  def change
    add_column :table_name, :column_name, :boolean, default: false
  end
end

** 3. Щоб внести зміни в таблицю бази даних додатків, запустіть таку команду в терміналі **

$ rake db:migrate

Чим це відрізняється від рейок 3+ або 2+?
Ruby Racer

2
Хтось знає, чи це було включено до Rails 5?
sambecker

9

Виконати:

rails generate migration add_column_to_table column:boolean

Це створить цю міграцію:

class AddColumnToTable < ActiveRecord::Migration
  def change
    add_column :table, :column, :boolean
  end
end

Встановіть додавання значень за замовчуванням: default => 1

add_column: table,: column,: boolean,: default => 1

Виконати:

rake db: мігрувати


2
Тепер значення за замовчуванням 1 не є абсолютно булевим;) Також цей іспит додає новий стовпець, замість того, щоб змінювати існуючий стовпець, чого і хотів досягти ОП
radiospiel

@radiospiel Насправді 1 булевий теж :)
kinduff

Вам також потрібно створити запис у таблиці із зовнішнім ключем з ідентифікатором 1 для цього, щоб уникнути цього Key is not present in table error.
Обіцяйте Престон

-50

Це те, що ви можете зробити:

class Profile < ActiveRecord::Base
  before_save :set_default_val

  def set_default_val
    self.send_updates = 'val' unless self.send_updates
  end
end

EDIT: ... але, мабуть, це новачок помилка!


Краще, якщо ви встановите за замовчуванням у схемі vs якbefore_save
rigelstpierre

6
Яка жахлива пропозиція
svelandiag

погодився, це дійсно страшно
Хоученг

3
ой, у вас є багато тепла для того, щоб робити щось на рівні моделі замість рівня бази даних. -38 - легендарна оцінка.
Нуреттін

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