Compruebe si existe una tabla en Rails

174

Tengo una tarea de rastrillo que no funcionará a menos que exista una tabla. Estoy trabajando con más de 20 ingenieros en un sitio web, así que quiero asegurarme de que hayan migrado la tabla antes de que puedan hacer una tarea de rastrillo que llenará esa tabla respectiva.

¿AR tiene un método como Table.exists? ¿Cómo puedo asegurarme de que hayan migrado la tabla correctamente?

thenengah
fuente
12
La broma dice ... cuántos ingenieros se necesitan para migrar una mesa :)
Zabba
1
En producción 1. En puesta en escena docenas y múltiples veces cada uno.
thenengah
2
¿No sería más fácil simplemente ejecutar las migraciones al comienzo de su tarea de rastrillo? Para que no tenga que preocuparse por la falta de tablas.
raskhadafi
@raskhadafi: Tenga en cuenta que las tablas faltantes le darán un problema si su configuración / inicializadores las usan. (es decir, incluso rake db:migratefallará.)
ocodo

Respuestas:

302

En Rails 5, la API se hizo explícita con respecto a tablas / vistas , colectivamente fuentes de datos .

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

En Rails 2, 3 y 4, la API trata sobre tablas .

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

Obtener el estado de las migraciones:

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

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

Si necesita más API para migraciones o metadatos, consulte:

capitanpete
fuente
44
ActiveRecord::Base.connection.table_exist 'users'buscaría una tabla de usuarios.
thenengah
44
ActiveRecord::Base.connection.table_exists? 'kittensbuscaría una mesa de gatito. ¡Eso es a menos que destruya a todos los gatitos! drop_table :kittens
thenengah
1
¡Gracias chicos! Acabo de usar.index_exists?('kittens', 'paws')
Viaje
14
Esto funciona para ActiveRecord 3.2.11 drop_table(:hosts_users) if table_exists? :hosts_users
Greg
1
ActiveRecord::Base.connection.data_source_exists? 'table_name'es el correcto ahora
Dorian
57

incluso si la tabla no existe:

modelo Kitten, kittens rieles de mesa esperados 3:

Kitten.table_exists? # => falso

alexey_the_cat
fuente
+ 1 Solución más elegante. También funciona si el modelo anula el nombre de la tabla.
Daniel Rikowski
1
Confirmar que esto funciona para Rails 2.3.18-lts (probado con una tabla presente, falta una antes de ejecutar el script / consola)
iheggie
32

Descubrí esto mientras intentaba eliminar una tabla a través de una migración:

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

funciona para Rails 3.2

Esta forma más simple estará disponible en Rails 5:

drop_table :kittens, if_exists: true

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

Y aquí está el CHANGELOG de Rails 5 ActiveRecord :

Introduzca la opción: if_exists para drop_table.

Ejemplo:

drop_table(:posts, if_exists: true)

Eso ejecutaría:

DROP TABLE IF EXISTS posts

Si la tabla no existe, if_exists: false (el valor predeterminado) genera una excepción, mientras que if_exists: true no hace nada.

kangkyu
fuente
Esto fallará si la tabla es de hecho una vista, ya que la tabla parecerá existir, pero DROP TABLE no puede soltarla.
mcr
8

Carriles 5.1

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

o

drop_table :table_name, if_exists: true
Vitor Oliveira
fuente
2
table_exists todavía funciona en rails-5, pero su comportamiento cambiará para verificar solo las tablas. A partir de 5.0.1, comprueba las vistas y las tablas. data_source_exists mantiene ese comportamiento y table_exists cambiará para verificar solo las tablas.
John Naegle
No está pidiendo verificar la tabla en una migración, debe asegurarse de que la tabla exista en una tarea de rastrillo
Juan Furattini
0

La forma correcta de hacer esto es Model.table_exists?

class Dog < ApplicationRecord
  # something
end

do_something if Dog.table_exists?
Juan Furattini
fuente