Ruby on Rails: Làm cách nào để tôi thêm một ràng buộc không null vào một cột hiện có bằng cách di chuyển?


130

Trong ứng dụng Rails (3.2) của tôi, tôi có một loạt các bảng trong cơ sở dữ liệu của mình nhưng tôi quên thêm một vài ràng buộc không null. Tôi đã đi vòng quanh nhưng tôi không thể tìm thấy cách viết di chuyển mà không thêm null vào một cột hiện có.

TIA.

Câu trả lời:


93

Đối với Rails 4+, câu trả lời của nates (sử dụng change_column_null ) sẽ tốt hơn.

Pre-Rails 4, hãy thử thay đổi_column .


25
Hãy cẩn thận với cách tiếp cận này - nếu bạn có các thuộc tính khác về cột đó (ví dụ: một :limitràng buộc), bạn cần lặp lại các thuộc tính đó khi sử dụng change_column, nếu không chúng sẽ bị mất. Vì lý do này, tôi thích sử dụng hơnchange_column_null
Nathan Wallace

Lưu ý rằng điều này tạo ra một IrreversibleMigrationcái có thể không phải là những gì bạn muốn.
Nic Nilov

@NicNilov bạn đang nói về câu trả lời HOẶC bình luận của Nathan Wallace?
Đánh dấu

@Mark Tôi đã nói về câu trả lời, xin lỗi vì không đủ cụ thể.
Nic Nilov

@NicNilov no dw Tôi đã nghĩ rằng mặc dù tôi chỉ muốn kiểm tra lại :)
Đánh dấu

273

Bạn cũng có thể sử dụng change_column_null :

change_column_null :table_name, :column_name, false

8
Câu trả lời sạch nhất!
Josh Bấm vào

1
Tôi đã phải thay đổi nó cho một loạt các cột và điều này không yêu cầu chỉ định loại cột cho mỗi cột, tốt hơn nhiều!
Dorian

1
Đây là câu trả lời tốt hơn. Trong cơ sở dữ liệu của tôi, tôi đã thêm một ràng buộc null trên một cột với các giá trị null tồn tại trước đó. change_column sẽ không cập nhật những giá trị đó. Theo tài liệu, change_column_null có giá trị thứ tư tùy chọn là giá trị mới cho bản cập nhật.
Merovex

Cảm ơn vì điều đó. Câu trả lời tốt nhất.
Ryan Rebo

1
tác dụng phụ thú vị .... quay ngược quá trình di chuyển sẽ đặt trường ngược lại (false -> true). Vì vậy, nếu bạn tạo di chuyển cho một số trường để thêm ràng buộc null và một số trường ALREADY có ràng buộc null, sau đó khôi phục di chuyển, nó sẽ XÓA ra ràng buộc null từ bất kỳ trường nào đã có nó.
jpw

10

1) FIRST: Thêm cột với giá trị mặc định

2) THEN: Xóa giá trị mặc định

add_column :orders, :items, :integer, null: false, default: 0
change_column :orders, :items, :integer, default: nil

2
Đây là giải pháp chính xác khi bạn cần thêm cột mới không phải là null, trước tiên bạn cần xác định rằng nó có giá trị mặc định vì SQLLite sẽ khiếu nại (Không thể thêm cột KHÔNG NULL với giá trị mặc định NULL), sau đó xóa nó!
Milan

2

Nếu bạn đang sử dụng nó trên một kịch bản / lược đồ tạo mới, đây là cách chúng ta có thể định nghĩa nó

class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
    t.string :name, null: false     # Notice here, NOT NULL definition
    t.string :email, null: false
    t.string :password, null: false
    t.integer :created_by
    t.integer :updated_by 

    t.datetime :created_at
    t.datetime :updated_at, default: -> { 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' }
   end
  end
end
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.