Saya perlu menambahkan cap waktu ( created_at
& updated_at
) ke tabel yang ada. Saya mencoba kode berikut tetapi tidak berhasil.
class AddTimestampsToUser < ActiveRecord::Migration
def change_table
add_timestamps(:users)
end
end
Saya perlu menambahkan cap waktu ( created_at
& updated_at
) ke tabel yang ada. Saya mencoba kode berikut tetapi tidak berhasil.
class AddTimestampsToUser < ActiveRecord::Migration
def change_table
add_timestamps(:users)
end
end
Pembantu cap waktu hanya tersedia di create_table
blok. Anda dapat menambahkan kolom ini dengan menentukan jenis kolom secara manual:
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
Meskipun ini tidak memiliki sintaks singkat yang sama dengan add_timestamps
metode yang telah Anda tentukan di atas, Rails masih akan memperlakukan kolom ini sebagai kolom timestamp, dan memperbarui nilai-nilai secara normal.
rails g migration AddTimestampsToUser created_at:datetime updated_at:datetime
- pintasan untuk menghasilkan migrasi di atas.PG::NotNullViolation: ERROR: column "created_at" contains null value
karena tabel saya sudah berisi data yang melanggar bukan batasan nol. Adakah cara yang lebih baik untuk melakukan ini daripada menghapus contraint yang tidak nol pada awalnya dan kemudian menambahkannya nanti?add_column :users, :updated_at, :datetime, null: false, default: Time.zone.now
.Time.zone.now
hanyalah sebuah contoh, Anda harus menggunakan nilai apa pun yang masuk akal untuk logika Anda.Migrasi hanyalah dua metode kelas (atau metode instance pada 3.1):
up
dandown
(dan terkadangchange
metode instance pada 3.1). Anda ingin perubahan Anda masuk keup
metode:Jika Anda berada di 3.1 maka Anda juga dapat menggunakan
change
(terima kasih Dave):Mungkin Anda membingungkan
def change
,def change_table
danchange_table
.Lihat panduan migrasi untuk detail lebih lanjut.
sumber
change
metode sekarang, meskipun dalam kasus ini, bukan masalahnya :)change
patut disebutkan jadi saya akan menambahkannya juga.Kode asli Anda sangat dekat dengan kanan, Anda hanya perlu menggunakan nama metode yang berbeda. Jika Anda menggunakan Rails 3.1 atau yang lebih baru, Anda perlu mendefinisikan
change
metode alih-alihchange_table
:Jika Anda menggunakan versi yang lebih lama, Anda perlu mendefinisikan
up
dandown
metode alih-alihchange_table
:sumber
Tanggapan @ user1899434 menjawab pada fakta bahwa tabel "yang ada" di sini bisa berarti tabel dengan catatan yang sudah ada di dalamnya, catatan yang mungkin tidak ingin Anda jatuhkan. Jadi, ketika Anda menambahkan cap waktu dengan null: false, yang merupakan default dan sering diinginkan, semua catatan yang ada semuanya tidak valid.
Tapi saya pikir jawaban itu dapat ditingkatkan, dengan menggabungkan dua langkah menjadi satu migrasi, serta menggunakan metode add_timestamps yang lebih semantik:
Anda dapat mengganti stempel waktu lain untuk
DateTime.now
, seperti jika Anda ingin catatan yang sudah ada dibuat / diperbarui pada waktu fajar sebagai gantinya.sumber
Time.zone.now
adalah apa yang harus digunakan jika kita ingin kode kita mematuhi zona waktu yang benar.Time.zone.now
yang akan mengembalikan contoh waktu yang dibuat ketika migrasi dijalankan dan cukup gunakan waktu itu sebagai default. Objek baru tidak akan mendapatkan instance Waktu baru.Transformasi yang tersedia adalah
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
sumber
Jawaban Nick Davies adalah yang paling lengkap dalam hal menambahkan kolom cap waktu ke tabel dengan data yang ada. Satu-satunya downside adalah bahwa ia akan naik
ActiveRecord::IrreversibleMigration
padadb:rollback
.Ini harus dimodifikasi agar berfungsi di kedua arah:
sumber
change_column_default
tidak mendukungfrom
danto
dalam versi itu?), Tapi saya mengambil ide ini dan menciptakanup/down
metode, bukan metode tunggalchange
dan itu bekerja seperti pesona!sumber
tidak yakin kapan tepatnya ini diperkenalkan, tetapi di rel 5.2.1 Anda bisa melakukan ini:
untuk lebih lanjut lihat " menggunakan metode perubahan " di dokumentasi migrasi catatan aktif.
sumber
, null: true
setelah:my_table
Saya membuat fungsi sederhana yang dapat Anda panggil untuk ditambahkan ke setiap tabel (dengan asumsi Anda memiliki database yang sudah ada) bidang Created_at dan updated_at :
sumber
Menambahkan kolom cap waktu (Created_at dan updated_at) ke table_name. Opsi tambahan (seperti null: false) diteruskan ke #add_column.
sumber
Jawaban sebelumnya tampaknya benar tetapi saya menghadapi masalah jika meja saya sudah memiliki entri.
Saya akan mendapatkan 'GALAT: kolom
created_at
berisinull
nilai'.Untuk memperbaikinya, saya menggunakan:
Saya kemudian menggunakan gem migration_data untuk menambahkan waktu untuk proyek saat ini pada migrasi seperti:
Kemudian semua proyek yang dibuat setelah migrasi ini akan diperbarui dengan benar. Pastikan server juga dinyalakan ulang sehingga Rails
ActiveRecord
mulai melacak cap waktu pada catatan.sumber
Banyak jawaban di sini, tetapi saya juga akan memposting jawaban saya karena tidak ada yang sebelumnya benar-benar bekerja untuk saya :)
Seperti yang telah dicatat oleh beberapa orang,
#add_timestamps
sayangnya menambahkannull: false
batasan, yang akan menyebabkan baris lama menjadi tidak valid karena mereka tidak memiliki nilai-nilai ini. Sebagian besar jawaban di sini menyarankan agar kami menetapkan beberapa nilai default (Time.zone.now
), tetapi saya tidak ingin melakukannya karena cap waktu default untuk data lama ini tidak akan benar. Saya tidak melihat nilai dalam menambahkan data yang salah ke tabel.Jadi migrasi saya hanyalah:
Tidak
null: false
, tidak ada batasan lain. Baris lama akan terus valid dengancreated_at
asNULL
, danupdate_at
asNULL
(hingga beberapa pembaruan dilakukan ke baris). Baris baru akan memilikicreated_at
danupdated_at
mengisi seperti yang diharapkan.sumber
Masalah dengan sebagian besar jawaban di sini adalah bahwa jika Anda default ke
Time.zone.now
semua catatan akan memiliki waktu migrasi dijalankan sebagai waktu default mereka, yang mungkin bukan yang Anda inginkan. Di rel 5 Anda bisa menggunakannow()
. Ini akan mengatur stempel waktu untuk catatan yang ada saat migrasi dijalankan, dan sebagai waktu mulai transaksi komit untuk catatan yang baru dimasukkan.class AddTimestampsToUsers < ActiveRecord::Migration def change add_timestamps :users, default: -> { 'now()' }, null: false end end
sumber
Menggunakan
Time.current
adalah gaya yang baik https://github.com/rubocop-hq/rails-style-guide#timenowatau
sumber
Ini sederhana untuk menambahkan cap waktu di tabel yang ada.
sumber
Bagi mereka yang tidak menggunakan Rails tetapi menggunakan activerecord, berikut ini juga menambahkan kolom ke model yang sudah ada, contohnya adalah untuk bidang integer.
sumber
Ini
change
, bukanchange_table
untuk Rails 4.2:sumber
Ini sepertinya solusi bersih di Rails 5.0.7 (menemukan metode change_column_null):
sumber
Saya di kereta 5.0 dan tidak ada opsi ini bekerja.
Satu-satunya hal yang berhasil adalah menggunakan tipe menjadi: timestamp dan bukan: datetime
sumber
Saya pribadi menggunakan yang berikut ini, dan memperbarui semua catatan sebelumnya dengan waktu / tanggal saat ini:
sumber
Saya mengalami masalah yang sama pada Rails 5 mencoba menggunakan
Saya dapat menambahkan kolom cap waktu secara manual dengan yang berikut:
sumber