Controlla se esiste una tabella in Rails


174

Ho un'attività di rake che non funzionerà se non esiste una tabella. Sto lavorando con più di 20 ingegneri su un sito Web, quindi voglio assicurarmi che abbiano migrato la tabella prima di poter eseguire un'attività di rake che popolerà la rispettiva tabella.

L'AR ha un metodo come Table.exists? Come posso assicurarmi che abbiano eseguito correttamente la migrazione della tabella?


12
Lo scherzo va ... quanti ingegneri ci vogliono per migrare un tavolo :)
Zabba,

1
Su produzione 1. Su messa in scena dozzine e più volte ciascuno.
thenengah,

2
Non sarebbe più semplice eseguire le migrazioni all'inizio dell'attività di rake? Quindi non devi preoccuparti delle tabelle mancanti.
Raskhadafi,

@Raskhadafi: Nota che le tabelle mancanti ti daranno un problema se le tue configurazioni / inizializzatori le usano. (cioè anche rake db:migratefallirà.)
Ocodo

Risposte:


302

In Rails 5 l' API è diventata esplicita per quanto riguarda tabelle / viste , origini dati collettivamente .

# 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 e 4 l'API riguarda le tabelle .

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

Ottenere lo stato delle migrazioni:

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

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

Se hai bisogno di più API per migrazioni o metadati vedi:


4
ActiveRecord::Base.connection.table_exist 'users'verificherebbe una tabella degli utenti.
thenengah

4
ActiveRecord::Base.connection.table_exists? 'kittenscontrollerebbe la presenza di un tavolo Kitten. Questo a meno che non abbia distrutto tutti i gattini! drop_table :kittens
thenengah

1
Grazie ragazzi! Ho appena usato.index_exists?('kittens', 'paws')
Viaggio

14
Funziona con ActiveRecord 3.2.11 drop_table(:hosts_users) if table_exists? :hosts_users
Greg,

1
ActiveRecord::Base.connection.data_source_exists? 'table_name'è quello corretto ora
Dorian

57

anche se la tabella non esiste:

modello Kitten, kittens binari della tabella previsti 3:

Kitten.table_exists? # => false


+ 1 soluzione più elegante. Funziona anche se il modello ha la precedenza sul nome della tabella.
Daniel Rikowski,

1
Confermando che questo funziona con Rails 2.3.18-lts (testato con una tabella presente, una mancante prima di eseguire script / console)
iheggie,

32

L'ho scoperto mentre cercavo di rimuovere una tabella tramite una migrazione:

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

funziona per Rails 3.2

Questo modulo più semplice sarà disponibile in Rails 5:

drop_table :kittens, if_exists: true

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

Ed ecco il CHANGELOG di ActiveRecord di Rails 5 :

Introdurre l'opzione: if_exists per drop_table.

Esempio:

drop_table(:posts, if_exists: true)

Ciò eseguirà:

DROP TABLE IF EXISTS posts

Se la tabella non esiste, if_exists: false (impostazione predefinita) solleva un'eccezione mentre if_exists: true non fa nulla.


Ciò fallirà se la tabella è effettivamente una vista, poiché la tabella sembrerà esistere, ma DROP TABLE non può rilasciarla.
MCR

8

Rotaie 5.1

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

o

drop_table :table_name, if_exists: true

2
table_exists funziona ancora in rails-5, ma il suo comportamento cambierà solo per controllare le tabelle. A partire da 5.0.1 controlla viste e tabelle. data_source_exists sostiene che il comportamento e table_exists cambieranno per controllare solo le tabelle.
John Naegle,

Non sta chiedendo di controllare la tabella su una migrazione, deve essere sicuro che la tabella esista su un'attività di rake
Juan Furattini,

0

Il modo corretto per farlo è Model.table_exists?

class Dog < ApplicationRecord
  # something
end

do_something if Dog.table_exists?
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.