Check if a table exists in Rails

Ruby on-RailsRubyRails ActiverecordRails Migrations

Ruby on-Rails Problem Overview


I have a rake task that won't work unless a table exists. I'm working with more than 20 engineers on a website so I want to make sure they have migrated the table before they can do a rake task which will populate that respective table.

Does AR have a method such as Table.exists? How can I make sure they have migrated the table successfully?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

In Rails 5 the API became explicit regarding tables/views, collectively data sources.

# 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'

In Rails 2, 3 & 4 the API is about tables.

# 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'

Getting the status of migrations:

# Tells you all migrations run
ActiveRecord::Migrator.get_all_versions

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

If you need more APIs for migrations or metadata see:

Solution 2 - Ruby on-Rails

even if table is not exists:

model Kitten, expected table kittens rails 3:

Kitten.table_exists? #=> false

Solution 3 - Ruby on-Rails

I found this out while I was trying to remove a table via a migration:

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

works for Rails 3.2

This simpler form will become available in Rails 5:

drop_table :kittens, if_exists: true

Reference: https://github.com/rails/rails/pull/16366

And here's the Rails 5 ActiveRecord's CHANGELOG:

> ## Introduce the :if_exists option for drop_table. > > Example: > > drop_table(:posts, if_exists: true) > That would execute: > > 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.

Solution 4 - Ruby on-Rails

Rails 5.1

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

or

drop_table :table_name, if_exists: true

Solution 5 - Ruby on-Rails

The proper way to do this is Model.table_exists?

class Dog < ApplicationRecord
  # something
end

do_something if Dog.table_exists?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionthenengahView Question on Stackoverflow
Solution 1 - Ruby on-RailscaptainpeteView Answer on Stackoverflow
Solution 2 - Ruby on-Railsalexey_the_catView Answer on Stackoverflow
Solution 3 - Ruby on-RailskangkyuView Answer on Stackoverflow
Solution 4 - Ruby on-RailsVitor OliveiraView Answer on Stackoverflow
Solution 5 - Ruby on-RailsJuan FurattiniView Answer on Stackoverflow