Проверьте, существует ли таблица в 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.