Rails-миграции: отменить настройку по умолчанию для столбца

190

У меня проблема в том, что у меня есть миграция в Rails, которая устанавливает настройки по умолчанию для столбца, как в следующем примере:

def self.up
  add_column :column_name, :bought_at, :datetime, :default => Time.now
end

Предположим, мне нравится отбрасывать эти настройки по умолчанию в более поздней миграции, как мне это сделать с помощью rails-миграций?

Мой текущий обходной путь - выполнение пользовательской команды sql в миграции rails, например:

def self.up
  execute 'alter table column_name alter bought_at drop default'
end

Но мне не нравится этот подход, потому что теперь я зависим от того, как базовая база данных интерпретирует эту команду. В случае изменения базы данных этот запрос, возможно, может больше не работать, и миграция будет прервана. Итак, есть ли способ выразить отмену настройки по умолчанию для столбца в рельсах?

wulfovitch
источник

Ответы:

387

Рельсы 5+

def change
  change_column_default( :table_name, :column_name, from: nil, to: false )
end

Рельсы 3 и Рельсы 4

def up
  change_column_default( :table_name, :column_name, nil )
end

def down
  change_column_default( :table_name, :column_name, false )
end
Джереми Мак
источник
7
В postgres это фактически не отбрасывает значение по умолчанию для CHARACTER VARYINGстолбцов, просто установите его на NULL::character varying.
Аттила О.
8
В более поздних версиях вы можете сделать его обратимым. Например: change_column_default(:table_name, :column_name, from: nil, to: false)
Отметить
1
@AttilaO. У меня был успех в беге ALTER TABLE table_name ALTER COLUMN type DROP DEFAULT, NULLя думаю , нет необходимости устанавливать его .
Эли Роуз - ВОССТАНОВИТЬ МОНИКУ
К вашему сведению, похоже, что обратимая версия, о которой упоминает @Mark, была добавлена ​​в Rails 5+, так что, если вы ниже этого уровня, вы не сможете ее использовать.
Джошуа Пинтер
23

Похоже, что вы правильно делаете со своим «execute», как указывают документы:

change_column_default(table_name, column_name, default)

Устанавливает новое значение по умолчанию для столбца. Если вы хотите установить значение по умолчанию NULL, вам не повезло. Вам нужно, чтобы DatabaseStatements # выполнил соответствующий оператор SQL самостоятельно. Примеры

change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)
Serx
источник
Спасибо! Я не нашел этот совет в документах сам! Надеюсь, что они встроены в сброс значений по умолчанию в миграцию в будущих версиях rails.
Вульфович
1
Это больше не так с Rails 3.1.0, cfr. apidock.com/rails/v3.1.0/ActiveRecord/ConnectionAdapters/…
асимметричный
14

Следующий фрагмент, который я использую для создания NULLстолбцов NOT NULL, но пропускаю DEFAULTна уровне схемы:

def self.up
  change_column :table, :column, :string, :null => false, :default => ""
  change_column_default(:table, :column, nil)
end
Алекс Фортуна
источник
Я не вижу добавленной стоимости в этом ответе, так как принятый заявляет то же самое.
Моссельман
-3

Рельсы 4

change_column :courses, :name, :string, limit: 100, null: false
Лесли Месть
источник
10
Это добавляет ограничение NOT NULL, оно не имеет ничего общего с DEFAULT
Extrapolator
не имеет ничего общего с DEFAULT +1
Иван Ван