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


174

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

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


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 для миграции или метаданных, смотрите:


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? # => ложь


+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 ничего не делает.


Это не удастся, если таблица на самом деле является представлением, так как эта таблица будет существовать, но 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 будет меняться только на проверку таблиц.
Джон Нэгл

Он не просит проверить таблицу на миграцию, он должен быть уверен, что таблица существует на грабли
Хуан Фураттини

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.