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?

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

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

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

23

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

change_column(:my_table, :my_column, :my_new_type)

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 :)).


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.