Ich habe eine Rake-Aufgabe, die nur funktioniert, wenn eine Tabelle existiert. Ich arbeite mit mehr als 20 Ingenieuren an einer Website. Ich möchte also sicherstellen, dass sie die Tabelle migriert haben, bevor sie eine Rake-Aufgabe 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?
In Rails 5 wurde die API explizit in Bezug auf Tabellen/Views , gemeinsam Datenquellen.
# 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 den Rails 2, 3 und 4 handelt es sich bei der API um tables.
# 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'
Status der Migrationen abrufen:
# 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, lesen Sie:
ActiveRecord::Base
-Klasse für die schema_migrations
-Tabelleauch wenn tabelle nicht existiert:
modell Kitten
, erwartete Tabelle kittens
Schienen 3:
Kitten.table_exists? # => falsch
Ich habe dies herausgefunden, als ich versuchte, 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)
arbeitet für Rails 3.2
Diese einfachere Form wird in Rails 5 verfügbar sein:
drop_table :kittens, if_exists: true
Referenz: https://github.com/Rails/rails/pull/16366
Und hier ist das CHANGELOG des 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 existiert, gibt if_exists: false (Standardeinstellung) eine Ausnahme aus, während if_exists: true nichts tut.
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
Der richtige Weg, dies zu tun, ist Model.table_exists?
class Dog < ApplicationRecord
# something
end
do_something if Dog.table_exists?