Überprüfen Sie, ob in Rails eine Tabelle vorhanden ist

174

Ich habe eine Rechenaufgabe, die nur funktioniert, wenn eine Tabelle vorhanden ist. Ich arbeite mit mehr als 20 Ingenieuren an einer Website, daher möchte ich sicherstellen, dass sie die Tabelle migriert haben, bevor sie eine Rechenaufgabe ausführen können, die die jeweilige Tabelle auffüllt.

Hat AR eine Methode wie Table.exists? Wie kann ich sicherstellen, dass die Tabelle erfolgreich migriert wurde?

thenengah
quelle
12
Der Witz geht .. wie viele Ingenieure braucht es, um eine Tabelle zu migrieren :)
Zabba
1
Bei der Produktion 1. Bei der Inszenierung von Dutzenden und jeweils mehrmals.
Thenengah
2
Wäre es nicht einfacher, die Migrationen einfach zu Beginn Ihrer Rake-Aufgabe auszuführen? Sie müssen sich also keine Sorgen über fehlende Tabellen machen.
Raskhadafi
@raskhadafi: Beachten Sie, dass fehlende Tabellen zu Problemen führen, wenn Ihre Konfigurations- / Initialisierer sie verwenden. (dh wird sogar rake db:migratescheitern.)
ocodo

Antworten:

302

In Rails 5 wurde die API in Bezug auf Tabellen / Ansichten und Datenquellen explizit .

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

In Rails 2, 3 und 4 handelt es sich bei der API um Tabellen .

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

Abrufen des Status von Migrationen:

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

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

Wenn Sie weitere APIs für Migrationen oder Metadaten benötigen, siehe:

Captainpete
quelle
4
ActiveRecord::Base.connection.table_exist 'users'würde nach einer Benutzertabelle suchen.
thenengah
4
ActiveRecord::Base.connection.table_exists? 'kittenswürde nach einem Kätzchentisch suchen. Es sei denn, ich habe alle Kätzchen vernichtet! drop_table :kittens
Thenengah
1
Danke Leute! Ich habe gerade.index_exists?('kittens', 'paws')
Trip
14
Dies funktioniert für ActiveRecord 3.2.11 drop_table(:hosts_users) if table_exists? :hosts_users
Greg
1
ActiveRecord::Base.connection.data_source_exists? 'table_name'ist jetzt die richtige
Dorian
57

auch wenn keine Tabelle vorhanden ist:

Modell Kitten, erwartete Tischschienen kittens 3:

Kitten.table_exists? # => false

alexey_the_cat
quelle
+ 1 Elegantere Lösung. Funktioniert auch, wenn das Modell den Tabellennamen überschreibt.
Daniel Rikowski
1
Bestätigen, dass dies für Rails 2.3.18-lts funktioniert (getestet mit einer vorhandenen Tabelle, eine fehlt, bevor das Skript / die Konsole ausgeführt wird)
iheggie
32

Ich habe dies herausgefunden, als ich versucht habe, eine Tabelle über eine Migration zu entfernen:

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

funktioniert für Rails 3.2

Dieses einfachere Formular wird in Rails 5 verfügbar sein:

drop_table :kittens, if_exists: true

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

Und hier ist der CHANGELOG von Rails 5 ActiveRecord :

Führen Sie die Option: if_exists für drop_table ein.

Beispiel:

drop_table(:posts, if_exists: true)

Das würde ausführen:

DROP TABLE IF EXISTS posts

Wenn die Tabelle nicht vorhanden ist, löst if_exists: false (Standardeinstellung) eine Ausnahme aus, während if_exists: true nichts bewirkt.

Kangkyu
quelle
Dies schlägt fehl, wenn es sich bei der Tabelle tatsächlich um eine Ansicht handelt, da die Tabelle anscheinend vorhanden ist, DROP TABLE sie jedoch nicht löschen kann.
mcr
8

Schienen 5.1

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

oder

drop_table :table_name, if_exists: true
Vitor Oliveira
quelle
2
table_exists funktioniert weiterhin in Rails-5, sein Verhalten ändert sich jedoch so, dass nur Tabellen überprüft werden. Ab 5.0.1 werden Ansichten und Tabellen überprüft. data_source_exists behält dieses Verhalten bei und table_exists ändert sich, um nur Tabellen zu überprüfen.
John Naegle
Er bittet nicht darum, die Tabelle auf eine Migration zu überprüfen, er muss sicher sein, dass die Tabelle auf einer
Rechenaufgabe
0

Der richtige Weg, dies zu tun, ist Model.table_exists?

class Dog < ApplicationRecord
  # something
end

do_something if Dog.table_exists?
Juan Furattini
quelle