O auxiliar de carimbo de data / hora está disponível apenas no create_table
bloco. Você pode adicionar essas colunas especificando os tipos de coluna manualmente:
class AddTimestampsToUser < ActiveRecord::Migration
def change_table
add_column :users, :created_at, :datetime, null: false
add_column :users, :updated_at, :datetime, null: false
end
end
Embora isso não tenha a mesma sintaxe concisa que o add_timestamps
método especificado acima, o Rails ainda tratará essas colunas como colunas de carimbo de data e hora e atualizará os valores normalmente.
rails g migration AddTimestampsToUser created_at:datetime updated_at:datetime
- um atalho para gerar a migração acima.PG::NotNullViolation: ERROR: column "created_at" contains null value
porque minha tabela já contém dados que violam restrições não nulas. Existe uma maneira melhor de fazer isso do que remover primeiro a contraint não nula e depois adicioná-la mais tarde?add_column :users, :updated_at, :datetime, null: false, default: Time.zone.now
.Time.zone.now
é apenas um exemplo, você deve usar qualquer valor que faça sentido para sua lógica.As migrações são apenas dois métodos de classe (ou métodos de instância na 3.1):
up
edown
(e às vezes umchange
método de instância na 3.1). Você deseja que suas alterações entrem noup
método:Se você estiver na versão 3.1, também poderá usar
change
(obrigado Dave):Talvez você está confuso
def change
,def change_table
echange_table
.Consulte o guia de migração para obter mais detalhes.
fonte
change
método agora, embora, neste caso, não é a questão :)change
vale a pena mencionar, então eu vou adicionar isso também.Seu código original está muito próximo da direita, você só precisa usar um nome de método diferente. Se você estiver usando o Rails 3.1 ou posterior, precisará definir um
change
método em vez dechange_table
:Se você estiver usando uma versão mais antiga, precisará definir
up
edown
métodos em vez dechange_table
:fonte
A resposta de @ user1899434 se deu conta de que uma tabela "existente" aqui poderia significar uma tabela com registros já nela, registros que talvez você não queira descartar. Portanto, quando você adiciona carimbos de data / hora com null: false, que é o padrão e geralmente desejável, esses registros existentes são todos inválidos.
Mas acho que essa resposta pode ser melhorada, combinando as duas etapas em uma migração e usando o método add_timestamps mais semântico:
Você pode substituir outro carimbo de data / hora
DateTime.now
, como se desejasse que os registros preexistentes fossem criados / atualizados logo no início.fonte
Time.zone.now
é o que deve ser usado se quisermos que nosso código obedeça ao fuso horário correto.Time.zone.now
que retornará a instância Time criada quando a migração for executada e usará esse horário como padrão. Novos objetos não receberão uma nova instância de Time.As transformações disponíveis são
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
fonte
A resposta de Nick Davies é a mais completa em termos de adição de colunas de carimbo de data / hora a uma tabela com dados existentes. Sua única desvantagem é que ele vai aumentar
ActiveRecord::IrreversibleMigration
em umdb:rollback
.Deve ser modificado da seguinte maneira para funcionar nas duas direções:
fonte
change_column_default
que não suportafrom
eto
nessa versão?), Mas peguei essa ideia e crieiup/down
métodos em vez de um únicochange
método e funcionou como um encanto!fonte
Não tenho certeza de quando exatamente isso foi introduzido, mas no Rails 5.2.1 você pode fazer isso:
para obter mais informações, consulte " usando o método de alteração " nos documentos de migração de registros ativos.
fonte
, null: true
after the:my_table
Eu criei uma função simples que você pode chamar para adicionar a cada tabela (supondo que você tenha um banco de dados existente) os campos created_at e updated_at :
fonte
Adiciona colunas de registro de data e hora (created_at e updated_at) ao nome_tabela. Opções adicionais (como null: false) são encaminhadas para #add_column.
fonte
As respostas anteriores parecem corretas, no entanto, eu enfrentei problemas se minha tabela já tiver entradas.
Eu receberia 'ERRO: a coluna
created_at
contémnull
valores'.Para consertar, eu usei:
Em seguida, usei o gem migration_data para adicionar o tempo para projetos atuais na migração, como:
Todos os projetos criados após essa migração serão atualizados corretamente. Verifique se o servidor também foi reiniciado para que o Rails
ActiveRecord
comece a rastrear os carimbos de data e hora no registro.fonte
Muitas respostas aqui, mas vou postar as minhas também porque nenhuma das anteriores realmente funcionou para mim :)
Como alguns observaram,
#add_timestamps
infelizmente , adiciona anull: false
restrição, o que fará com que as linhas antigas sejam inválidas porque elas não têm esses valores preenchidos. A maioria das respostas aqui sugere que definimos algum valor padrão (Time.zone.now
), mas eu não gostaria de fazer isso porque esses carimbos de data e hora padrão para dados antigos não estarão corretos. Não vejo o valor em adicionar dados incorretos à tabela.Então, minha migração foi simplesmente:
Não
null: false
, não há outras restrições. As linhas antigas continuarão sendo válidas comcreated_at
asNULL
eupdate_at
asNULL
(até que alguma atualização seja realizada na linha). Novas linhas terãocreated_at
e serãoupdated_at
preenchidas conforme o esperado.fonte
O problema com a maioria das respostas aqui é que, se você usar como padrão
Time.zone.now
todos os registros, terá o tempo em que a migração foi executada como o tempo padrão, o que provavelmente não é o que você deseja. Nos trilhos 5, você pode usarnow()
. Isso definirá os registros de data e hora dos registros existentes como a hora em que a migração foi executada e como a hora de início da transação de confirmação dos registros inseridos recentemente.class AddTimestampsToUsers < ActiveRecord::Migration def change add_timestamps :users, default: -> { 'now()' }, null: false end end
fonte
Usar
Time.current
é um bom estilo https://github.com/rubocop-hq/rails-style-guide#timenowou
fonte
É simples adicionar um registro de data e hora na tabela existente.
fonte
Para aqueles que não usam o Rails, mas usam o activerecord, o seguinte também adiciona uma coluna a um modelo existente, por exemplo, um campo inteiro.
fonte
É
change
, nãochange_table
para Rails 4.2:fonte
Parece uma solução limpa no Rails 5.0.7 (descoberto o método change_column_null):
fonte
Estou nos trilhos 5.0 e nenhuma dessas opções funcionou.
A única coisa que funcionou foi usar o tipo a ser: timestamp e não: datetime
fonte
Eu pessoalmente usei o seguinte e ele atualizou todos os registros anteriores com a hora / data atual:
fonte
Corri para o mesmo problema no Rails 5 tentando usar
Consegui adicionar as colunas de carimbo de data / hora manualmente com o seguinte:
fonte