By Jason Whitehorn


2010-10-26 01:52:32 8 Comments

I added a table that I thought I was going to need, but now no longer plan on using it. How should I remove that table?

I've already run migrations, so the table is in my database. I figure rails generate migration should be able to handle this, but I haven't figured out how yet.

I've tried:

rails generate migration drop_tablename

but that just generated an empty migration.

What is the "official" way to drop a table in Rails?

19 comments

@aqwan 2017-11-20 16:15:28

Alternative to raising exception or attempting to recreate a now empty table - while still enabling migration rollback, redo etc -

def change
  drop_table(:users, force: true) if ActiveRecord::Base.connection.tables.include?('users')
end

@Nitin Rakesh 2016-06-17 13:21:47

Run this command:-

rails g migration drop_table_name

then:

rake db:migrate

or if you are using MySql database then:

  1. login with database
  2. show databases;
  3. show tables;
  4. drop table_name;

@Tom Lord 2016-06-17 13:27:12

Does this answer add anything to the existing, accepted answer? If not, there's no need to post this.

@bert bruynooghe 2017-04-25 09:40:22

this creates an empty migration in rails 4.2, as already stated in the question itself.

@webaholik 2018-06-23 17:52:21

This is EXACTLY what the OP originally tried...this answer should be removed

@lllllll 2012-11-08 22:38:02

While the answers provided here work properly, I wanted something a bit more 'straightforward', I found it here: link First enter rails console:

$rails console

Then just type:

ActiveRecord::Migration.drop_table(:table_name)

And done, worked for me!

@Grant Birchmeier 2013-02-28 18:56:27

That doesn't create a migration. It just drops the table using the migration class. Asker is looking to create a migration that drops the table.

@lllllll 2013-03-01 07:54:57

@GrantBirchmeier: I definetely agree that this is neither the official nor the best way to drop the table. However I believe the asker isn't looking specifically to create a migration that drops the table. He/She is literally asking first for a "a way to remove the table", where my answer could be of use. And latter for the official way to drop the table, where my answer would not be a very recommended option at all, since a migration is more appropiate.

@BC2 2014-06-23 19:14:45

HI vint-i-vuit how if i accidentally delete the wrong table. How do i reverse it? Currently used your method but accidentally drop the wrong table.

@lllllll 2014-06-24 16:31:19

@BC2: What do you mean by reverse it exactly? If by that you mean the actual contents of the rows, I'm afraid you can't go back, unless you kept a backup of your db. On the other hand, if you just want to recreate the same schema you had before(hence also the wrongly deleted table), why not just remigrate with bundle exec rake db:migrate? Note: I'm assuming you are in development environment, so the actual content is not relevant.

@BC2 2014-06-24 16:38:28

@vint-i-vuit haha yea i'm in development env. Is ok I've solved it =). Thanks anyway =)

@gm2008 2014-07-13 12:29:37

The model is still there until you run rails destroy model User

@zee 2017-08-23 14:13:51

Only run this if you want to get rid of the table for good. Rails will be unaware of this drop. Migration is broken after running this command. Can not CREATE, DROP...ETC. ERROR SQLite3::SQLException: no such table: accruals: DROP TABLE "sometable"

@Nicollas Matheus 2018-06-02 22:17:17

if you want to drop a specific table you can do

$ rails db:migrate:up VERSION=[Here you can insert timestamp of table]

otherwise if you want to drop all your database you can do

$rails db:drop

@Pankaj Dhote 2018-04-20 14:54:46

Drop Table/Migration

run:- $ rails generate migration DropTablename

exp:- $ rails generate migration DropProducts

@webaholik 2018-06-23 17:05:15

This will result in same issue as OP mentioned: an empty migration file. Still need to add drop_table :table_name to generated file.

@Mahesh Mesta 2017-07-28 06:57:26

The simple and official way would be this:

  rails g migration drop_tablename

Now go to your db/migrate and look for your file which contains the drop_tablename as the filename and edit it to this.

    def change
      drop_table :table_name
    end

Then you need to run

    rake db:migrate 

on your console.

@Obromios 2017-08-28 03:17:23

If the table has foreign indices, you will need to do drop_table :golfers, force: :cascade

@Matheus Silva 2017-05-05 17:42:34

You can roll back a migration the way it is in the guide:

http://guides.rubyonrails.org/active_record_migrations.html#reverting-previous-migrations

Generate a migration:

rails generate migration revert_create_tablename

Write the migration:

require_relative '20121212123456_create_tablename'

class RevertCreateTablename < ActiveRecord::Migration[5.0]
  def change
    revert CreateTablename    
  end
end

This way you can also rollback and can use to revert any migration

@Pete 2010-10-26 01:54:46

You won't always be able to simply generate the migration to already have the code you want. You can create an empty migration and then populate it with the code you need.

You can find information about how to accomplish different tasks in a migration here:

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

More specifically, you can see how to drop a table using the following approach:

drop_table :table_name

@berkes 2011-01-17 20:04:22

This worked for me too. But on full migrations (installing from scratch) the table will now be first created and later on dropped again. Is it safe to remove the create and drop migrations down the road?

@Pete 2011-01-19 00:52:12

If no other migration uses that table (adding/removing columns, adjusting column attributes, etc.) then it might not harm anything to remove the create/drop migrations. However I'm not sure removing them will buy you any significant improvements. Is there some particular reason you're looking to remove them?

@william tell 2012-05-11 16:23:25

Any view here on whether it's better to drop tables or revert to a previous database schema?

@Pete 2012-05-11 21:57:42

If you're done with the table and do not plan to use it anymore, I'd say just drop it. Better to get rid of it if its not being used.

@onerinas 2016-05-03 06:28:12

answer by @BederAcostaBorges is more self-explanatory and accurate

@Martin Konicek 2018-05-08 16:14:47

How to also remove all foreign keys? There are columns in other tables pointing to the table being dropped.

@Toby 1 Kenobi 2018-08-17 12:05:22

If you also want the migration to be reversible then add a block to the drop_table method that looks like what you would give to a create_table method, that way if you did a rollback the table structure would be created again joshfrankel.me/blog/…

@Rankit Ranjan 2015-08-03 12:00:33

Run

rake db:migrate:down VERSION=<version>

Where <version> is the version number of your migration file you want to revert.

Example:-

rake db:migrate:down VERSION=3846656238

@Shahzad Tariq 2015-05-26 07:42:53

You need to to create a new migration file using following command

rails generate migration drop_table_xyz

and write drop_table code in newly generated migration file (db/migration/xxxxxxx_drop_table_xyz) like

drop_table :tablename

Or if you wanted to drop table without migration, simply open rails console by

$ rails c

and execute following command

ActiveRecord::Base.connection.execute("drop table table_name")

or you can use more simplified command

ActiveRecord::Migration.drop_table(:table_name)

@Jason Whitehorn 2015-05-28 19:15:23

Not to be picky, but you're 5 years late to this question and the answer you provide has been mentioned multiple times before.

@Abel 2016-12-07 03:52:09

@jason-whitehorn 5 years late, but is the best summary 👍🏻

@Farzpal Singh 2015-10-16 06:59:32

you can simply drop a table from rails console. first open the console

$ rails c

then paste this command in console

ActiveRecord::Migration.drop_table(:table_name)

replace table_name with the table you want to delete.

you can also drop table directly from the terminal. just enter in the root directory of your application and run this command

$ rails runner "Util::Table.clobber 'table_name'"

@Brian Dear 2017-03-23 09:18:58

And then when you run your migrations later, you get the table back. Terrible idea to drop tables in Rails outside of migrations because the schema would then have diverged from the migrations. That break Rails convention.

@Farzpal Singh 2017-04-07 09:52:25

Of course you have to delete the migration file too. And also these are the ideas if you are working on local, if your code is on server then it is good to create new migration file for deleting table or if you are server expert too then you can simply delete the migration file and drop table from console to on server.

@Anoob K Bava 2015-09-14 12:52:03

the best way you can do is

rails g migration Drop_table_Users

then do the following

rake db:migrate

@bert bruynooghe 2017-04-25 09:40:58

creates an empty migration, as already state in the question.

@webaholik 2018-06-23 17:55:42

ANSWER SHOULD BE DELETED - SAME AS OP's original attempt - creates an empty migration

@Aashish Saini 2015-07-31 14:20:13

  1. rails g migration drop_users
  2. edit the migration
    class DropUsers < ActiveRecord::Migration
      def change
        drop_table :users do |t|
          t.string :name
          t.timestamps
        end
      end
    end
  1. rake db:migrate

@Brian Dear 2017-03-23 09:17:19

This is a great answer because it provides a reversible migration. The other answers will drop the table, but if you attempt a rollback, this answer provides the ability to rollback.

@Beder Acosta Borges 2015-07-27 15:25:02

Write your migration manually. E.g. run rails g migration DropUsers.

As for the code of the migration I'm just gonna quote Maxwell Holder's post Rails Migration Checklist

BAD - running rake db:migrate and then rake db:rollback will fail

class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users
  end
end

GOOD - reveals intent that migration should not be reversible

class DropUsers < ActiveRecord::Migration
  def up
    drop_table :users
  end

  def down
    fail ActiveRecord::IrreversibleMigration
  end
end

BETTER - is actually reversible

class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users do |t|
      t.string :email, null: false
      t.timestamps null: false
    end
  end
end

@zx1986 2016-04-12 04:14:19

follow the docs: guides.rubyonrails.org/…

@B Seven 2016-08-12 23:04:33

Rolling back your "BAD" code raises "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)." I think this is more helpful than the error raised by fail ActiveRecord::IrreversibleMigration better? Rails 4.1.6

@Beder Acosta Borges 2016-08-18 13:14:17

@BSeven I see your point, but I still prefer the "GOOD" migration to the "BAD" migration because it explicitly states that there's no going back without some manual work. If you like the explanatory text you can add it to the exception with fail ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)." See Active Record Migrations

@B Seven 2016-08-18 18:09:39

@BederAcostaBorges - Yes, that's better. Well, actually it's better than GOOD, not as good as BETTER.

@cimnine 2016-10-03 07:22:21

Just be aware, that once dropped, the data will be gone anyways. There's no real "going back" from dropping a table, it's just that the database structure is the same as before. If there were references from other tables to this one, those will most likely be invalid/broken after the rollback as well.

@nhegroj 2014-09-08 22:16:08

ActiveRecord::Base.connection.drop_table :table_name

@6ft Dan 2014-11-14 16:08:31

You're missing one : symbol between ActiveRecord and Base

@manish nautiyal 2012-12-14 06:41:05

Open you rails console

ActiveRecord::Base.connection.execute("drop table table_name")

@webaholik 2018-06-23 18:00:17

This simply removes the table. It does not create a migration, nor address the original migration. Next time db:migrate runs, the table will be recreated.

@Aaron Henderson 2013-02-13 20:55:07

I needed to delete our migration scripts along with the tables themselves ...

class Util::Table < ActiveRecord::Migration

 def self.clobber(table_name)   
    # drop the table
    if ActiveRecord::Base.connection.table_exists? table_name
      puts "\n== " + table_name.upcase.cyan + " ! " 
           << Time.now.strftime("%H:%M:%S").yellow
      drop_table table_name 
    end

    # locate any existing migrations for a table and delete them
    base_folder = File.join(Rails.root.to_s, 'db', 'migrate')
    Dir[File.join(base_folder, '**', '*.rb')].each do |file|
      if file =~ /create_#{table_name}.rb/
        puts "== deleting migration: " + file.cyan + " ! "
             << Time.now.strftime("%H:%M:%S").yellow
        FileUtils.rm_rf(file)
        break
      end
    end
  end

  def self.clobber_all
    # delete every table in the db, along with every corresponding migration 
    ActiveRecord::Base.connection.tables.each {|t| clobber t}
  end

end

from terminal window run:

$ rails runner "Util::Table.clobber 'your_table_name'"

or

$ rails runner "Util::Table.clobber_all"

@webaholik 2018-06-23 18:04:06

Interesting approach, great if changes are only local - to make it more complete, code should be added to remove VERSION from the schema_migrations table. If changes are not local...this is completely WRONG and works against the purpose migrations.

@Brandon O'Rourke 2011-10-15 18:57:14

First generate an empty migration with any name you'd like. It's important to do it this way since it creates the appropriate date.

rails generate migration DropProductsTable

This will generate a .rb file in /db/migrate/ like 20111015185025_drop_products_table.rb

Now edit that file to look like this:

class DropProductsTable < ActiveRecord::Migration
  def up
    drop_table :products
  end

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

The only thing I added was drop_table :products and raise ActiveRecord::IrreversibleMigration.

Then run rake db:migrate and it'll drop the table for you.

@mjnissim 2013-11-22 21:50:13

Or you could use the same code above, only that in the down method, put code to re-create the table like create_table :products etc. But in any case, I find this answer more comprehensive and useful than the accepted one.

@fflyer05 2014-01-09 01:34:44

A down migration should be used to recreate the table being dropped.

@mhriess 2014-04-04 17:07:19

This migration could never be rolled back, even in development. Would it be better to just leave the down migration blank?

@Zack Shapiro 2014-06-15 08:25:45

This is the better answer + fflyer's comment

@Sebastialonso 2015-01-23 16:43:23

@mjnissim and fflyer05 are correct, in order to avoid any weird thing you should recreate the table in the down method.

@user3402754 2017-01-23 15:26:29

To make the migration reversible, modify the code as follows. I prefer to use the change method, instead of having a separate up and down method, so the same code works both ways def change; drop_table :products do |t|; t.string :product_name, null: false; t.timestamps null: false; end; end;

@Francis Potter 2011-04-03 22:50:40

I think, to be completely "official", you would need to create a new migration, and put drop_table in self.up. The self.down method should then contain all the code to recreate the table in full. Presumably that code could just be taken from schema.rb at the time you create the migration.

It seems a little odd, to put in code to create a table you know you aren't going to need anymore, but that would keep all the migration code complete and "official", right?

I just did this for a table I needed to drop, but honestly didn't test the "down" and not sure why I would.

@digitalWestie 2011-07-12 15:20:06

Strange but it looks like I'm going to have to do this too.

@Steph Rose 2012-03-14 15:55:55

Or you can just use: raise ActiveRecord::IrreversibleMigration in the self.down method, so you at LEAST give yourself an error / notice if you ever try to rollback.

@Isaac Betesh 2013-06-05 14:45:52

I would test the down just because otherwise I'm introducing untested code into my project. How can I reuse the original migration's up method? I've tried CreateMyTable.up and ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X) where X is the migration that originally created the table, but neither works--in both approaches, AR first checks whether the migration has already been applied, and silently skips it if it has. `

Related Questions

Sponsored Content

16 Answered Questions

[SOLVED] How to drop columns using Rails migration

25 Answered Questions

[SOLVED] How can I rename a database column in a Ruby on Rails migration?

6 Answered Questions

9 Answered Questions

[SOLVED] How does database indexing work?

18 Answered Questions

[SOLVED] Purge or recreate a Ruby on Rails database

10 Answered Questions

[SOLVED] Sequelize.js: how to use migrations and sync

7 Answered Questions

[SOLVED] Rails migration for change column

6 Answered Questions

3 Answered Questions

[SOLVED] Backwards migration with Django South

2 Answered Questions

[SOLVED] Generated Rails Models - how will the Migrations run?

Sponsored Content