Kiểm tra nếu một bảng tồn tại trong Rails


174

Tôi có một nhiệm vụ cào không hoạt động trừ khi có bảng. Tôi đang làm việc với hơn 20 kỹ sư trên một trang web vì vậy tôi muốn chắc chắn rằng họ đã di chuyển bảng trước khi họ có thể thực hiện một nhiệm vụ cào sẽ đưa vào bảng tương ứng.

AR có phương pháp Table.existsnào không? Làm thế nào tôi có thể chắc chắn rằng họ đã di chuyển bảng thành công?


12
Trò đùa diễn ra .. cần bao nhiêu kỹ sư để di chuyển một bảng :)
Zabba

1
Về sản xuất 1. Trên dàn hàng chục và nhiều lần mỗi.
thenengah

2
Sẽ không dễ dàng hơn nếu chỉ chạy di chuyển khi bắt đầu nhiệm vụ cào của bạn? Vì vậy, bạn không phải lo lắng về việc thiếu bảng.
raskhadafi

@raskhadafi: Lưu ý rằng các bảng bị thiếu sẽ gây ra sự cố nếu cấu hình / bộ khởi tạo của bạn sử dụng chúng. (tức là thậm chí rake db:migratesẽ thất bại.)
ocodo

Câu trả lời:


302

Trong Rails 5, API trở nên rõ ràng về các bảng / lượt xem , các nguồn dữ liệu chung .

# Tables and views
ActiveRecord::Base.connection.data_sources
ActiveRecord::Base.connection.data_source_exists? 'kittens'

# Tables
ActiveRecord::Base.connection.tables
ActiveRecord::Base.connection.table_exists? 'kittens'

# Views
ActiveRecord::Base.connection.views
ActiveRecord::Base.connection.view_exists? 'kittens'

Trong Rails 2, 3 & 4 API là về các bảng .

# Listing of all tables and views
ActiveRecord::Base.connection.tables

# Checks for existence of kittens table/view (Kitten model)
ActiveRecord::Base.connection.table_exists? 'kittens'

Lấy trạng thái di chuyển:

# Tells you all migrations run
ActiveRecord::Migrator.get_all_versions

# Tells you the current schema version
ActiveRecord::Migrator.current_version

Nếu bạn cần thêm API để di chuyển hoặc siêu dữ liệu, hãy xem:


4
ActiveRecord::Base.connection.table_exist 'users'sẽ kiểm tra bảng người dùng.
thenengah

4
ActiveRecord::Base.connection.table_exists? 'kittenssẽ kiểm tra một bảng mèo con. Đó là trừ khi tôi tiêu diệt tất cả mèo con! drop_table :kittens
thenengah

1
Cảm ơn các bạn! Tôi vừa mới sử dụng.index_exists?('kittens', 'paws')
Chuyến đi

14
Điều này hoạt động cho ActiveRecord 3.2.11 drop_table(:hosts_users) if table_exists? :hosts_users
Greg

1
ActiveRecord::Base.connection.data_source_exists? 'table_name'bây giờ là chính xác
Dorian

57

ngay cả khi bảng không tồn tại:

mô hình Kitten, kittens đường ray bảng dự kiến 3:

Kitten.table_exists? # => sai


+ 1 Giải pháp thanh lịch hơn. Cũng hoạt động nếu mô hình ghi đè tên bảng.
Daniel Rikowski

1
Xác nhận điều này hoạt động cho Rails 2.3,18-lts (được thử nghiệm với một bảng hiện tại, một bảng bị thiếu trước khi chạy tập lệnh / bảng điều khiển)
iheggie

32

Tôi đã tìm thấy điều này trong khi tôi đang cố xóa bảng thông qua di chuyển:

drop_table :kittens if (table_exists? :kittens)
ActiveRecord::Migration.drop_table :kittens if (ActiveRecord::Base.connection.table_exists? :kittens)

hoạt động cho Rails 3.2

Hình thức đơn giản hơn này sẽ có sẵn trong Rails 5:

drop_table :kittens, if_exists: true

Tham khảo: https://github.com/rails/rails/pull/16366

Và đây là RANG 5 ActiveRecord's CHANGELOG :

Giới thiệu tùy chọn: if_exists cho drop_table.

Thí dụ:

drop_table(:posts, if_exists: true)

Điều đó sẽ thực thi:

DROP TABLE IF EXISTS posts

Nếu bảng không tồn tại, if_exists: false (mặc định) sẽ đưa ra một ngoại lệ trong khi if_exists: true không có gì.


Điều này sẽ thất bại nếu trên thực tế bảng là một khung nhìn, vì bảng sẽ xuất hiện, nhưng DROP TABLE không thể loại bỏ nó.
mcr

8

Đường ray 5.1

if ActiveRecord::Base.connection.data_source_exists? 'table_name'
   drop_table :table_name
end

hoặc là

drop_table :table_name, if_exists: true

2
table_exists vẫn hoạt động trong rails-5, nhưng hành vi của nó sẽ thay đổi thành chỉ kiểm tra các bảng. Kể từ 5.0.1, nó kiểm tra các khung nhìn và các bảng. data_source_exists giữ hành vi đó và table_exists sẽ thay đổi thành chỉ kiểm tra các bảng.
John Naegle

Anh ta không yêu cầu kiểm tra bàn khi di chuyển, anh ta cần chắc chắn rằng bàn tồn tại trong một nhiệm vụ cào
Juan Furattini

0

Cách thích hợp để làm điều này là Model.table_exists?

class Dog < ApplicationRecord
  # something
end

do_something if Dog.table_exists?
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.