Thay đổi loại cột từ Ngày thành Ngày Thời gian trong khi di chuyển ROR


227

Tôi cần thay đổi loại cột của mình từ ngày sang datetime cho một ứng dụng tôi đang thực hiện. Tôi không quan tâm đến dữ liệu vì nó vẫn đang được phát triển.

Tôi có thể làm cái này như thế nào?

Câu trả lời:


508

Đầu tiên trong thiết bị đầu cuối của bạn:

rails g migration change_date_format_in_my_table

Sau đó, trong tệp di chuyển của bạn:

Đối với đường ray> = 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
Bạn nói đúng, tôi chỉ cho rằng một người mới bắt đầu sẽ chọn công nghệ mới nhất hiện có, nhưng điều đó, tất nhiên, không chắc chắn
bắt đầu

12
Câu hỏi được gắn thẻ "ruby-on-rails-3"
Sucrenoir

2
@Sucrenoir Vâng, thẻ đã được thêm vào bằng cách xin lỗi sau khi anh ấy trả lời.
Jason

10
Nếu bạn đang tự hỏi tại sao một đơn changephương không được sử dụng thay cho updownphương pháp, đó là vì các changephương pháp không hỗ trợ các change_columnđịnh nghĩa di cư .
Dennis

2
Câu trả lời này chỉ đúng một phần, bạn không thể sử dụng Change_column bên trong thay đổi ngay cả trên đường ray 4 hoặc di chuyển xuống sẽ không hoạt động. Bạn nên sử dụng lên / xuống bất kể phiên bản đường ray.
Alan Peabody

78

Ngoài ra, nếu bạn đang sử dụng Rails 3 hoặc mới hơn, bạn không phải sử dụng các phương thức updown. Bạn chỉ có thể sử dụng change:

class ChangeFormatInMyTable < ActiveRecord::Migration
  def change
    change_column :my_table, :my_column, :my_new_type
  end
end

78
Phương pháp thay đổi chỉ hoạt động với di chuyển đảo ngược. Đoạn mã trên sẽ đưa ra một ngoại lệ ActiveRecord :: IrreversibleMigration. Chỉ nên sử dụng các phương thức trong api.rubyonrails.org/groupes/ActiveRecord/Migration/ mẹo trong phương thức thay đổi.
davekaro

3
Tôi đang chạy Rails 4 và đã thực hiện kiểu di chuyển này trước đây. THAY ĐỔI KHÔNG LÀM VIỆC! Nhận xét của @ davekaro là chính xác.
harryt

3
Đối với Rails 5, đây là giải pháp chính xác và hiệu quả.
WM

3
Khi bị đảo ngược, làm thế nào để biết loại cột cũ cần thay đổi trở lại là gì?
Andrew Grimm

@AndrewGrimm bạn đúng. Đây là những gì tôi thấy khi tôi cố gắng đảo ngược quá trình di chuyển của mình: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

Trong Rails 3.2 và Rails 4, câu trả lời phổ biến của Benjamin có cú pháp hơi khác nhau.

Đầu tiên trong thiết bị đầu cuối của bạn:

$ rails g migration change_date_format_in_my_table

Sau đó, trong tệp di chuyển của bạn:

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

Có một phương thức change_column , chỉ cần thực hiện nó trong di chuyển của bạn với datetime là một kiểu mới.

change_column(:my_table, :my_column, :my_new_type)

1
Điều này có bảo tồn dữ liệu gốc?
BKSpurgeon

1
Có, bảo toàn dữ liệu gốc
Mauro

1

AFAIK, di chuyển ở đó để cố gắng định hình lại dữ liệu bạn quan tâm (nghĩa là sản xuất) khi thực hiện thay đổi lược đồ. Vì vậy, trừ khi điều đó sai và vì anh ta đã nói rằng anh ta không quan tâm đến dữ liệu, tại sao không sửa đổi loại cột trong di chuyển ban đầu từ ngày sang datetime và chạy lại di chuyển? (Hy vọng bạn đã có bài kiểm tra :)).


2
Bạn có khả năng quan tâm đến việc sử dụng di chuyển trong môi trường phát triển, ngay cả khi bạn không quan tâm đến dữ liệu, nếu bạn đang làm việc trong một nhóm và bạn muốn thay đổi lược đồ của mình lan truyền đến tất cả các nhà phát triển khác trong nhóm của bạn.
Jose B

Tôi gặp khó khăn khi thấy lợi thế nào khi di chuyển bổ sung để thay đổi một cột mang lại cho bạn trong tình huống này. Điều gì là sai với việc thay đổi di chuyển ban đầu đã tạo ra cột? Trong cả hai trường hợp, mỗi thành viên trong nhóm phải chạy lại tất cả các lần di chuyển để có được lược đồ mới.
fakeleft

Nếu bạn sử dụng di chuyển mới, bạn có thể hoàn tác di chuyển đã thay đổi loại cột. Nếu bạn chỉnh sửa bản gốc, bạn sẽ phải quay lại chỉnh sửa đó và chạy lại các lần di chuyển sau đó.
jazzpi

Đây thực sự là một câu trả lời rất thận trọng vì chưa có dữ liệu sản xuất. Đối với những người lo lắng về các thành viên khác trong nhóm, đó là những gì rake db:migrate:resetdành cho.
Ryan McGeary
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.