关于ruby:检查Rails中是否存在表

Check if a table exists in Rails

我有一个rake任务,除非存在一个表,否则它将无效。 我在一个网站上与20多名工程师一起工作,所以我想确保他们已经迁移了表,然后才能执行一个rake任务,该任务将填充相应的表。

AR是否有Table.exists等方法? 如何确保他们已成功迁移表?


在Rails 5中,API变得明确关于表/视图,统称数据源。

1
2
3
4
5
6
7
8
9
10
11
# 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是关于表的。

1
2
3
4
5
# 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'

获取迁移状态:

1
2
3
4
5
# Tells you all migrations run
ActiveRecord::Migrator.get_all_versions

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

如果您需要更多用于迁移或元数据的API,请参阅:

  • 的ActiveRecord :: SchemaMigration
    这是schema_migrations表的ActiveRecord::Base
  • 的ActiveRecord ::迁移
    迁移运行时所有操作都发生的位置


即使表不存在:

model Kitten,期望表kittens
铁轨3:

Kitten.table_exists? #=> false


我在尝试通过迁移删除表时发现了这个问题:

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

适用于Rails 3.2

这个更简单的形式将在Rails 5中提供:

1
drop_table :kittens, if_exists: true

参考:https://github.com/rails/rails/pull/16366

这是Rails 5 ActiveRecord的CHANGELOG:

Introduce the :if_exists option for drop_table.

Example:

1
drop_table(:posts, if_exists: true)

That would execute:

1
DROP TABLE IF EXISTS posts

If the table doesn't exist, if_exists: false (the default) raises an exception whereas if_exists: true does nothing.


Rails 5.1

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

要么

1
drop_table :table_name, if_exists: true


正确的方法是Model.table_exists?

1
2
3
4
5
class Dog < ApplicationRecord
  # something
end

do_something if Dog.table_exists?