Di chuyển Rails: Hoàn tác cài đặt mặc định cho một cột


190

Tôi có một vấn đề, đó là tôi có một di chuyển trong Rails thiết lập cài đặt mặc định cho một cột, như ví dụ này:

def self.up
  add_column :column_name, :bought_at, :datetime, :default => Time.now
end

Giả sử, tôi muốn bỏ cài đặt mặc định đó trong lần di chuyển sau, làm thế nào để tôi làm điều đó với việc sử dụng di chuyển đường ray?

Cách giải quyết hiện tại của tôi là việc thực thi lệnh sql tùy chỉnh trong di chuyển đường ray, như thế này:

def self.up
  execute 'alter table column_name alter bought_at drop default'
end

Nhưng tôi không thích cách tiếp cận này, vì bây giờ tôi phụ thuộc vào cách cơ sở dữ liệu cơ bản diễn giải lệnh này. Trong trường hợp thay đổi cơ sở dữ liệu, truy vấn này có thể không hoạt động nữa và quá trình di chuyển sẽ bị phá vỡ. Vì vậy, có cách nào để thể hiện hoàn tác cài đặt mặc định cho một cột trong đường ray không?

Câu trả lời:


387

Đường ray 5+

def change
  change_column_default( :table_name, :column_name, from: nil, to: false )
end

Rails 3 và Rails 4

def up
  change_column_default( :table_name, :column_name, nil )
end

def down
  change_column_default( :table_name, :column_name, false )
end

7
Trong postgres, điều này sẽ không thực sự bỏ mặc định cho CHARACTER VARYINGcác cột, chỉ cần đặt nó thành NULL::character varying.
Attila O.

8
Trong các phiên bản gần đây hơn, bạn có thể làm cho nó đảo ngược. Ví dụ: change_column_default(:table_name, :column_name, from: nil, to: false)
Đánh dấu

1
@AttilaO. Tôi đã chạy thành công ALTER TABLE table_name ALTER COLUMN type DROP DEFAULT, tôi không cần thiết lập nó NULL.
Eli Rose - REINSTATE MONICA

FYI, có vẻ như phiên bản đảo ngược mà @Mark đề cập đã được thêm vào trong Rails 5+, vì vậy, bất cứ điều gì dưới đây, bạn sẽ không thể sử dụng nó.
Joshua Pinter

23

Âm thanh như bạn đang làm điều đúng với 'thực thi' của bạn, như các tài liệu chỉ ra:

change_column_default(table_name, column_name, default)

Đặt giá trị mặc định mới cho cột. Nếu bạn muốn đặt giá trị mặc định thành NULL, bạn không gặp may. Bạn cần phải DatabaseStatements # tự thực thi câu lệnh SQL thích hợp. Ví dụ

change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)

Cảm ơn! Tôi đã không tìm thấy gợi ý này trong các tài liệu một mình! Hopefull họ xây dựng trong việc giảm các giá trị mặc định thành di chuyển trong các phiên bản tương lai của đường ray.
wulfovitch

1
Điều này không còn đúng nữa kể từ Rails 3.1.0, cfr. apidock.com/rails/v3.1.0/ActiveRecord/ConnectionAd Chap
đối

14

Đoạn mã sau tôi sử dụng để tạo NULLcột NOT NULL, nhưng bỏ qua DEFAULTở cấp lược đồ:

def self.up
  change_column :table, :column, :string, :null => false, :default => ""
  change_column_default(:table, :column, nil)
end

Tôi không thấy giá trị gia tăng trong câu trả lời này vì câu hỏi được chấp nhận giống nhau.
Mosselman

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.