2009-10-29 14 views
53

tôi đang làm loại điều trong cuộc di cư của tôi:Rails Migrations: Kiểm tra sự tồn tại và tiếp tục đi?

add_column :statuses, :hold_reason, :string rescue puts "column already added" 

nhưng nó chỉ ra rằng, trong khi làm việc này cho SQLite, nó không hoạt động cho PostgreSQL. Dường như nếu add_column thổi lên, ngay cả khi ngoại lệ bị bắt, giao dịch đã chết và vì vậy, Di chuyển không thể thực hiện bất kỳ công việc bổ sung nào.

Có bất kỳ không DB khác biệt cách kiểm tra xem cột hoặc bảng đã tồn tại chưa? Không, có cách nào để có được khối cứu hộ của tôi thực sự hoạt động không?

Trả lời

132

Kể từ Rails 3.0 trở lên, bạn có thể sử dụng column_exists? để kiểm tra sự tồn tại của cột.

unless column_exists? :statuses, :hold_reason 
    add_column :statuses, :hold_reason, :string 
end 

Ngoài ra còn có chức năng table_exists?, quay trở lại như Rails 2.1.

+0

có coi Pract tốt nhất băng để kiểm tra xem một cột/bảng có tồn tại trước khi thêm/tạo nó không? (Tôi biết tất nhiên nó phụ thuộc vào vấn đề trong tay) –

+2

Điều này làm việc với rollbacks nếu tôi xác định nó trong phương pháp thay đổi? – dardub

+0

Vâng rollback sẽ là một vấn đề ... chúng tôi không chắc chắn liệu chúng ta nên loại bỏ các cột hay không .. kể từ khi chúng tôi không ghi lại trạng thái trước đó. – songyy

4

Đối Rails 2.X, bạn có thể kiểm tra sự tồn tại của các cột như sau:

columns("[table-name]").index {|col| col.name == "[column-name]"} 

Nếu nó trả về nil, không có cột như vậy tồn tại. Nếu nó trả về một Fixnum, thì cột đó tồn tại. Đương nhiên, bạn có thể đặt các thông số chọn lọc hơn giữa {...} nếu bạn muốn xác định một cột bằng cách nhiều hơn chỉ là tên gọi của nó, ví dụ:

{ |col| col.name == "foo" and col.sql_type == "tinyint(1)" and col.primary == nil } 

(đáp này lần đầu tiên được đăng trên How to write conditional migrations in rails?)

0

add_column: trạng thái ,: hold_reason,: chuỗi trừ Status.column_names.include ("hold_reason")

5

Hoặc thậm chí ngắn hơn

add_column :statuses, :hold_reason, :string unless column_exists? :statuses, :hold_reason 
+0

đây sẽ là nhận xét về câu trả lời khác, không phải là câu trả lời. Cảm ơn. –

Các vấn đề liên quan