Periksa apakah ada tabel di Rails

174

Saya memiliki tugas menyapu yang tidak akan berfungsi kecuali jika ada meja. Saya bekerja dengan lebih dari 20 insinyur di sebuah situs web sehingga saya ingin memastikan mereka telah memigrasi tabel sebelum mereka dapat melakukan tugas menyapu yang akan mengisi tabel masing-masing.

Apakah AR memiliki metode seperti itu Table.exists? Bagaimana saya bisa memastikan mereka berhasil memigrasi tabel?

thenengah
sumber
12
Lelucon berjalan .. berapa banyak insinyur yang diperlukan untuk memigrasi meja :)
Zabba
1
Pada produksi 1. Pada Pementasan masing-masing puluhan dan beberapa kali.
thenengah
2
Bukankah lebih mudah menjalankan migrasi pada awal tugas menyapu Anda? Jadi Anda tidak perlu khawatir tentang meja yang hilang.
raskhadafi
@raskhadafi: Perhatikan bahwa tabel yang hilang akan memberi Anda masalah jika konfigurasi / inisialisasi Anda menggunakannya. (Yaitu bahkan rake db:migrateakan gagal.)
ocodo

Jawaban:

302

Dalam Rails 5 API menjadi eksplisit mengenai tabel / tampilan , secara kolektif sumber data .

# 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'

Di Rails 2, 3 & 4 API adalah tentang tabel .

# 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'

Mendapatkan status migrasi:

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

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

Jika Anda membutuhkan lebih banyak API untuk migrasi atau metadata, lihat:

kapten
sumber
4
ActiveRecord::Base.connection.table_exist 'users'akan memeriksa tabel pengguna.
thenengah
4
ActiveRecord::Base.connection.table_exists? 'kittensakan memeriksa meja Kitten. Itu kecuali aku menghancurkan semua anak kucing! drop_table :kittens
thenengah
1
Terima kasih kawan! Saya baru saja menggunakan.index_exists?('kittens', 'paws')
Trip
14
Ini berfungsi untuk ActiveRecord 3.2.11 drop_table(:hosts_users) if table_exists? :hosts_users
Greg
1
ActiveRecord::Base.connection.data_source_exists? 'table_name'adalah yang benar sekarang
Dorian
57

bahkan jika tabel tidak ada:

model Kitten, kittens rel meja yang diharapkan 3:

Kitten.table_exists? # => salah

alexey_the_cat
sumber
+1 Solusi yang lebih elegan. Juga berfungsi jika model menimpa nama tabel.
Daniel Rikowski
1
Mengkonfirmasi ini berfungsi untuk Rails 2.3.18-lts (diuji dengan satu hadiah tabel, satu hilang sebelum menjalankan skrip / konsol)
iheggie
32

Saya menemukan ini ketika saya mencoba untuk menghapus tabel melalui migrasi:

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

bekerja untuk Rails 3.2

Formulir sederhana ini akan tersedia di Rails 5:

drop_table :kittens, if_exists: true

Referensi: https://github.com/rails/rails/pull/16366

Dan inilah CHANGELOG Rails 5 ActiveRecord :

Perkenalkan opsi: if_exists untuk drop_table.

Contoh:

drop_table(:posts, if_exists: true)

Itu akan mengeksekusi:

DROP TABLE IF EXISTS posts

Jika tabel tidak ada, if_exists: false (default) memunculkan exception sedangkan if_exists: true tidak melakukan apa-apa.

kangkyu
sumber
Ini akan gagal jika tabel sebenarnya adalah tampilan, karena tabel akan tampak ada, tetapi DROP TABLE tidak dapat menjatuhkannya.
mcr
8

Rel 5.1

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

atau

drop_table :table_name, if_exists: true
Vitor Oliveira
sumber
2
table_exists masih berfungsi di rails-5, tetapi perilakunya akan berubah menjadi hanya memeriksa tabel. Pada 5.0.1 ia memeriksa tampilan dan tabel. data_source_exists menjaga perilaku itu dan table_exists akan berubah menjadi hanya memeriksa tabel.
John Naegle
Dia tidak meminta untuk memeriksa tabel tentang migrasi, dia perlu memastikan bahwa tabel ada pada tugas menyapu
Juan Furattini
0

Cara yang tepat untuk melakukan ini adalah Model.table_exists?

class Dog < ApplicationRecord
  # something
end

do_something if Dog.table_exists?
Juan Furattini
sumber