Перевірте, чи існує таблиця в Rails


174

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

Чи є у AR такий метод, як Table.exists? Як я можу переконатися, що вони успішно перенесли таблицю?


12
Жарт іде .. скільки інженерів потрібно, щоб перенести стіл :)
Zaba

1
Про виробництво 1. На постановці десятки і кілька разів кожна.
thenengah

2
Чи не було б простіше просто запустити міграцію на початку завдання граблі? Тож вам не доведеться турбуватися про відсутні таблиці.
raskhadafi

@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'перевірив би таблицю користувачів.
thenengah

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

І ось рейках 5 ActiveRecord в CHANGELOG :

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

Приклад:

drop_table(:posts, if_exists: true)

Це буде виконувати:

DROP TABLE IF EXISTS posts

Якщо таблиці не існує, if_exists: false (за замовчуванням) створює виняток, тоді як if_exists: true нічого не робить.


Це не вдасться, якщо таблиця насправді є переглядом, оскільки таблиця, здається, існує, але DROP TABLE не може її скинути.
mcr

8

Рейки 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 все ще працює в рейках-5, але його поведінка буде змінюватися лише на контрольні таблиці. Станом на 5.0.1 він перевіряє види та таблиці. data_source_exists зберігає, що поведінка та table_exists будуть змінюватися лише на контрольні таблиці.
Джон Нагіль

Він не просить перевірити таблицю на міграцію, йому потрібно бути впевненим, що таблиця існує на граблях
Хуан Фураттіні

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.