Проверьте, существует ли таблица в Rails

174

У меня есть грабли, которые не будут работать, если таблица не существует. Я работаю с более чем 20 инженерами на веб-сайте, поэтому я хочу убедиться, что они перенесли таблицу, прежде чем они смогут выполнить задачу rake, которая заполнит эту соответствующую таблицу.

Есть ли у AR такой метод, как Table.exists? Как я могу убедиться, что они успешно перенесли таблицу?

thenengah
источник
12
Шутка идет .. сколько инженеров нужно, чтобы перенести таблицу :)
Забба
1
На производстве 1. На постановке десятки и несколько раз каждый.
Тоенга
2
Не проще ли запустить миграцию при запуске граблей? Так что вам не нужно беспокоиться о пропущенных таблицах.
Расхадафи
@raskhadafi: обратите внимание, что пропущенные таблицы могут вызвать проблемы, если ваши конфиг / инициализаторы их используют. (то есть даже rake db:migrateпотерпит неудачу.)
ocodo

Ответы:

302

В Rails 5 API стало явным в отношении таблиц / представлений , в совокупности источников данных .

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

В Rails 2, 3 и 4 API касается таблиц .

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

Получение статуса миграций:

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

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

Если вам нужно больше API для миграции или метаданных, смотрите:

captainpete
источник
4
ActiveRecord::Base.connection.table_exist 'users'проверил бы для таблицы пользователей.
затем
4
ActiveRecord::Base.connection.table_exists? 'kittensпроверил бы для таблицы котенка. Это если я не уничтожил всех котят! drop_table :kittens
thenengah
1
Спасибо, парни! Я просто использовал.index_exists?('kittens', 'paws')
Поездка
14
Это работает для ActiveRecord 3.2.11 drop_table(:hosts_users) if table_exists? :hosts_users
Грег
1
ActiveRecord::Base.connection.data_source_exists? 'table_name'сейчас правильный
Дориан
57

даже если таблица не существует:

Модель Kitten, ожидаемый стол kittens рельсов 3:

Kitten.table_exists? # => ложь

alexey_the_cat
источник
+1 Более элегантное решение. Также работает, если модель переопределяет имя таблицы.
Даниэль Риковски
1
Подтверждение того, что это работает для Rails 2.3.18-lts (проверено с одной присутствующей таблицей, одна отсутствует перед запуском скрипта / консоли)
iheggie
32

Я узнал об этом, когда пытался удалить таблицу с помощью миграции:

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

работает для Rails 3.2

Эта более простая форма станет доступной в Rails 5:

drop_table :kittens, if_exists: true

Ссылка: https://github.com/rails/rails/pull/16366

А вот CHANGELOG в Rails 5 ActiveRecord :

Введите параметр: if_exists для drop_table.

Пример:

drop_table(:posts, if_exists: true)

Что бы выполнить:

DROP TABLE IF EXISTS posts

Если таблица не существует, if_exists: false (по умолчанию) вызывает исключение, тогда как if_exists: true ничего не делает.

kangkyu
источник
Это не удастся, если таблица на самом деле является представлением, так как эта таблица будет существовать, но DROP TABLE не сможет ее удалить.
Mc
8

Rails 5.1

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

или

drop_table :table_name, if_exists: true
Витор Оливейра
источник
2
table_exists все еще работает в rails-5, но его поведение будет меняться только на проверку таблиц. Начиная с 5.0.1 он проверяет представления и таблицы. data_source_exists сохраняет это поведение, а table_exists будет меняться только на проверку таблиц.
Джон Нэгл
Он не просит проверить таблицу на миграцию, он должен быть уверен, что таблица существует на грабли
Хуан Фураттини
0

Правильный способ сделать это - Model.table_exists?

class Dog < ApplicationRecord
  # something
end

do_something if Dog.table_exists?
Хуан Фураттини
источник