Ubah jenis kolom dari Date to DateTime selama migrasi ROR

227

Saya perlu mengubah jenis kolom saya dari tanggal ke waktu untuk aplikasi yang saya buat. Saya tidak peduli dengan data karena masih sedang dikembangkan.

Bagaimana saya bisa melakukan ini?

jdog
sumber

Jawaban:

508

Pertama di terminal Anda:

rails g migration change_date_format_in_my_table

Kemudian di file migrasi Anda:

Untuk Rails> = 3.2:

class ChangeDateFormatInMyTable < ActiveRecord::Migration
  def up
    change_column :my_table, :my_column, :datetime
  end

  def down
    change_column :my_table, :my_column, :date
  end
end
apneadiving
sumber
27
Anda benar, saya hanya berasumsi bahwa seorang pemula akan memilih teknologi terbaru yang tersedia, tetapi itu, tentu saja, tidak pasti
apneadiving
12
Pertanyaan itu ditandai "ruby-on-rails-3"
Sucrenoir
2
@ Cucrenoir Ya tag ditambahkan oleh apneadiving setelah dia menjawab.
Jason
10
Jika Anda bertanya-tanya mengapa satu changemetode tidak digunakan sebagai pengganti updan downmetode, itu karena para changemetode tidak mendukung change_columndefinisi migrasi .
Dennis
2
Jawaban ini hanya sebagian benar, Anda tidak dapat menggunakan change_column dalam perubahan bahkan pada rel 4 atau migrasi turun tidak akan berfungsi. Anda harus menggunakan atas / bawah, apa pun versi relnya.
Alan Peabody
78

Juga, jika Anda menggunakan Rails 3 atau yang lebih baru, Anda tidak harus menggunakan updan downmetode. Anda bisa menggunakan change:

class ChangeFormatInMyTable < ActiveRecord::Migration
  def change
    change_column :my_table, :my_column, :my_new_type
  end
end
Lee McAlilly
sumber
78
Metode perubahan hanya berfungsi dengan migrasi yang dapat dibalik. Kode di atas akan membuang pengecualian ActiveRecord :: IrreversibleMigration. Hanya metode di api.rubyonrails.org/classes/ActiveRecord/Migration/… yang harus digunakan dalam metode perubahan.
davekaro
3
Saya menjalankan Rails 4 dan melakukan migrasi semacam ini sebelumnya. PERUBAHAN TIDAK BEKERJA! Komentar @ davekaro benar.
harryt
3
Untuk Rails 5, ini adalah solusi yang benar dan berfungsi.
WM
3
Saat dibalik, bagaimana ia bisa tahu jenis kolom lama yang harus diubah kembali?
Andrew Grimm
@AndrewGrimm Anda benar. Inilah yang saya lihat ketika saya mencoba membalikkan migrasi saya:This migration uses change_column, which is not automatically reversible. To make the migration reversible you can either: 1. Define #up and #down methods in place of the #change method. 2. Use the #reversible method to define reversible behavior.
Marklar
42

Dalam Rails 3.2 dan Rails 4, jawaban populer Benjamin memiliki sintaks yang sedikit berbeda.

Pertama di terminal Anda:

$ rails g migration change_date_format_in_my_table

Kemudian di file migrasi Anda:

class ChangeDateFormatInMyTable < ActiveRecord::Migration
  def up
   change_column :my_table, :my_column, :datetime
  end

  def down
   change_column :my_table, :my_column, :date
  end
end
Thomas Klemm
sumber
23

Ada metode change_column , jalankan saja dalam migrasi Anda dengan datetime sebagai tipe baru.

change_column(:my_table, :my_column, :my_new_type)
Nikita Rybak
sumber
1
apakah ini mempertahankan data asli?
BKSpurgeon
1
Ya, simpan data asli
Mauro
1

AFAIK, ada migrasi untuk mencoba membentuk kembali data yang Anda pedulikan (yaitu produksi) ketika membuat perubahan skema. Jadi, kecuali itu salah, dan karena dia memang mengatakan dia tidak peduli dengan data, mengapa tidak hanya memodifikasi tipe kolom dalam migrasi asli dari tanggal ke datetime dan menjalankan kembali migrasi? (Semoga Anda punya tes :)).

fakeleft
sumber
2
Anda berpotensi peduli tentang menggunakan migrasi di lingkungan pengembangan, bahkan jika Anda tidak peduli dengan data, jika Anda bekerja dalam tim dan Anda ingin skema Anda disebarkan ke semua pengembang lain di tim Anda.
Jose B
Saya mengalami masalah dalam melihat keuntungan apa yang dimiliki migrasi tambahan untuk mengubah kolom dalam situasi ini. Apa yang salah dengan mengubah migrasi asli yang membuat kolom? Dalam setiap kasus, setiap anggota tim harus menjalankan kembali semua migrasi untuk mendapatkan skema baru.
fakeleft
Jika Anda menggunakan migrasi baru, Anda bisa membatalkan migrasi yang mengubah tipe kolom. Jika Anda mengedit yang asli, Anda harus mengembalikan edit itu dan menjalankan kembali migrasi setelah itu.
jazzpi
Ini sebenarnya jawaban yang sangat bijaksana mengingat belum ada data produksi. Bagi mereka yang mengkhawatirkan anggota tim lain, itulah gunanya rake db:migrate:reset.
Ryan McGeary