Di chuyển đường ray: self.up và self.down so với thay đổi


86

Có vẻ như phiên bản rails mới có các phương thức "thay đổi" so với self.up và self.down.

Vì vậy, điều gì sẽ xảy ra khi một người phải quay lại một quá trình di chuyển, làm thế nào nó biết những hành động cần thực hiện. Tôi có phương pháp sau mà tôi cần triển khai dựa trên một hướng dẫn trực tuyến:

class AddImageToUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :image_file_name, :string
    add_column :users, :image_content_type, :string
    add_column :users, :image_file_size, :integer
    add_column :users, :image_updated_at, :datetime
  end

  def self.down
    remove_column :users, :image_file_name, :string
    remove_column :users, :image_content_type, :string
    remove_column :users, :image_file_size, :integer
    remove_column :users, :image_updated_at, :datetime
  end    
end

Làm cách nào tôi có thể làm điều tương tự bằng cách sử dụng phương pháp thay đổi mới?


Câu trả lời:


110

Đối với nhiều hoạt động, đường ray có thể đoán được đâu là hoạt động nghịch đảo (không có vấn đề). Ví dụ, trong trường hợp của bạn, thao tác ngược lại add_columnđể gọi khi bạn khôi phục là gì? Tất nhiên rồi remove_column. Nghịch đảo của là create_tablegì? Nó drop_table. Vì vậy, trong những trường hợp này, rails biết cách khôi phục và xác định một downphương thức là không cần thiết (bạn có thể xem trong tài liệu các phương thức hiện được hỗ trợ từ phương thức thay đổi ).

Nhưng hãy chú ý vì đối với một số loại hoạt động bạn vẫn cần xác định downphương pháp , ví dụ: nếu bạn thay đổi độ chính xác của một cột thập phân, làm thế nào để đoán độ chính xác ban đầu khi khôi phục? Nó không thể, vì vậy bạn cần xác định downphương pháp.

Như đã nói, tôi khuyên bạn nên đọc Hướng dẫn Di chuyển Rails .


33

Tốt hơn để sử dụng Up, Down, Change:

Trên Rails 3 (Có thể đảo ngược): sẽ thêm cột mới lên và chỉ điền tất cả các bản ghi trong bảng lên và chỉ xóa cột này khi xuống

def up
  add_column :users, :location, :string
  User.update_all(location: 'Minsk')
end

def down
  remove_column :users, :location
end

Nhưng:

Bạn phải tránh sử dụng phương pháp thay đổi để tiết kiệm thời gian. Ví dụ: nếu bạn không cần cập nhật giá trị cột ngay lập tức sau khi nó thêm, bạn sẽ cắt mã này xuống như thế này:

def change
  add_column :users, :location, :string
end

Trên đó, nó sẽ thêm cột vào bảng và xóa nó xuống. Mã ít hơn nhiều và đó là lợi nhuận.

Trên Rails 4: một cách hữu ích hơn để viết những gì chúng ta cần vào một nơi:

def change
  add_column :users, :location, :string
  reversible do |direction|
    direction.up { User.update_all(location: 'Minsk') }
  end
end

Đẹp giải thích bro
Bibek Sharma

hoàn nguyên? cũng là một cách tốt để biết hướng bạn đang đi bên trong sự thay đổi
baash05

Không cái nào trong số này hiệu quả. Tôi chỉ tiếp tục nhận được ActiveRecord::IrreversibleMigration.
Ném tài khoản vào

có những tình huống mà đường ray không thể khôi phục lại quá trình di chuyển. vui lòng xem trợ giúp
Kaleem Ullah

1
class AddImageToUsers < ActiveRecord::Migration
  def change
    add_column :users, :image_file_name, :string
    add_column :users, :image_content_type, :string
    add_column :users, :image_file_size, :integer
    add_column :users, :image_updated_at, :datetime
  end
end

Cảm ơn. Nhưng điều gì sẽ xảy ra nếu bạn quay trở lại. nó sẽ biết phải làm gì?
banditKing

3
Tôi ngủ quá giấc. Aldo 'xoen' Giambelluca giải thích mọi thứ.
không có gì-đặc-biệt-ở đây,
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.