Railsにテーブルが存在するかどうかを確認する


174

テーブルが存在しないと機能しないRakeタスクがあります。私はWebサイトで20人以上のエンジニアと作業しているので、それぞれのテーブルにデータを取り込むレーキタスクを実行する前に、テーブルを移行したことを確認します。

ARには次のような方法がありTable.existsますか?テーブルが正常に移行されたことをどのように確認できますか?


12
ジョークは..テーブルを移行するのに何人のエンジニアが必要か:)
Zabba

1
本番環境1.ステージングを数十回、各回。
thenengah

2
レーキタスクの開始時に移行を実行するだけの方が簡単ではないでしょうか。そのため、テーブルの欠落を心配する必要はありません。
raskhadafi 2012

@raskhadafi:config / initializersが使用している場合、欠落しているテーブルが問題を引き起こすことに注意してください。(つまり、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?#=> false


+ 1よりエレガントなソリューション。モデルがテーブル名をオーバーライドする場合にも機能します。
ダニエルリコウスキー2013

1
これがRails 2.3.18-ltsで機能することを確認(1つのテーブルが存在することをテスト済み、スクリプト/コンソールを実行する前に1つが存在しない)
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

そして、これがRails 5 ActiveRecordのCHANGELOGです。

drop_tableに:if_existsオプションを導入。

例:

drop_table(:posts, if_exists: true)

それは実行されます:

DROP TABLE IF EXISTS posts

テーブルが存在しない場合、if_exists:false(デフォルト)は例外を発生させますが、if_exists:trueは何もしません。


テーブルが実際にビューである場合、テーブルは存在するように見えるため、これは失敗しますが、DROP TABLEはそれをドロップできません。
mcr 2016年

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はテーブルのチェックのみに変更されます。
John Naegle 2017年

彼は移行時にテーブルを確認するように求めていません。テーブルが
レーキタスクに

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.