Migrações Rails: desfaz a configuração padrão para uma coluna

190

Eu tenho o problema, que eu tenho uma migração no Rails que define uma configuração padrão para uma coluna, como este exemplo:

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

Suponha que eu gostaria de eliminar essas configurações padrão em uma migração posterior. Como faço isso usando migrações de trilhos?

Minha solução atual é a execução de um comando sql personalizado na migração de rails, assim:

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

Mas não gosto dessa abordagem, porque agora estou dependente de como o banco de dados subjacente está interpretando esse comando. Em caso de alteração do banco de dados, talvez essa consulta não funcione mais e a migração seja interrompida. Então, existe uma maneira de expressar o desfazer de uma configuração padrão para uma coluna nos trilhos?

wulfovitch
fonte

Respostas:

387

Rails 5+

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

Trilhos 3 e Trilhos 4

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

def down
  change_column_default( :table_name, :column_name, false )
end
Jeremy Mack
fonte
7
No postgres, isso realmente não descarta o padrão para as CHARACTER VARYINGcolunas, apenas defina-o como NULL::character varying.
Attila O.
8
Nas versões mais recentes, você pode torná-lo reversível. Por exemplo: change_column_default(:table_name, :column_name, from: nil, to: false)
Marque
1
@AttilaO. Eu tive sucesso em execução ALTER TABLE table_name ALTER COLUMN type DROP DEFAULT, não há necessidade de configurá-lo para NULLeu acho.
Eli Rose - REINSTATE MONICA
Para sua informação, parece que a versão reversível mencionada pelo @Mark foi adicionada no Rails 5+, portanto, qualquer coisa abaixo disso, você não poderá usá-lo.
Joshua Pinter
23

Parece que você está fazendo a coisa certa com o seu 'execute', como os documentos apontam:

change_column_default(table_name, column_name, default)

Define um novo valor padrão para uma coluna. Se você deseja definir o valor padrão como NULL, está sem sorte. Você precisa # DatabaseStatements executar a instrução SQL apropriada. Exemplos

change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)
Serx
fonte
Obrigado! Não encontrei essa dica nos documentos sozinho! Esperamos que eles construam a queda dos valores padrão nas migrações em futuras versões dos trilhos.
Wulfovitch 20/05/09
1
Isso não é mais verdade a partir do Rails 3.1.0, cfr. apidock.com/rails/v3.1.0/ActiveRecord/ConnectionAdapters/…
assimétrico
14

O seguinte trecho que eu uso para criar NULLcolunas NOT NULL, mas pular DEFAULTno nível do esquema:

def self.up
  change_column :table, :column, :string, :null => false, :default => ""
  change_column_default(:table, :column, nil)
end
Alex Fortuna
fonte
Não vejo valor agregado nesta resposta, já que a aceita declara o mesmo.
21912 Mosselman
-3

Trilhos 4

change_column :courses, :name, :string, limit: 100, null: false
Lesly Revenge
fonte
10
Este adiciona restrição NOT NULL, não tem nada a ver com DEFAULT
Extrapolator
não tem nada a ver com DEFAULT +1
Ivan Wang