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?
3
24 Answers
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
8
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?
– berkesAny view here on whether it’s better to drop tables or revert to a previous database schema?
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.
– PeteHow to also remove all foreign keys? There are columns in other tables pointing to the table being dropped.
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.
6
A down migration should be used to recreate the table being dropped.
– fflyer05This migration could never be rolled back, even in development. Would it be better to just leave the down migration blank?
– mhriessThis is the better answer + fflyer’s comment
@mjnissim and fflyer05 are correct, in order to avoid any weird thing you should recreate the table in the down method.
Dropping a table deletes all the data, if you recreate it in the
down
method you won’t recover it so it’s not actually a proper roll back. It’s better to clearly indicate that the migration is irreversible than to give a false sense that it can be recovered from.– vivi
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
2
If you’re cutting and pasting into the block from
schema.rb
, don’t forget to also searchschema.rb
for foreign keys. Then add the foreign key definition to thedrop_table
block, e.g.:t.foreign_key "other_table"
I used the 3rd option and it worked perfectly fine for me. Thank you.
Warning: Do this at your own risk, as @z-atef and @nzifnab correctly point out, Rails will not be aware of these changes, your migration sequence fill fail and your schema will be different from your coworkers’. This is meant as a resource for locally tinkering with development only.
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!
3
The model is still there until you run
rails destroy model User
– gm2008Only 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”
– z atefWARNING: DO NOT DO THIS. You should never ever perform DDL operations on your database straight from the console. Your structure file will have no idea this change was made, your coworkers development environments will be different from your own and from production, it’s just a mess. Use migrations.
– nzifnab
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)
0
- rails g migration drop_users
- edit the migration
class DropUsers < ActiveRecord::Migration
def change
drop_table :users do |t|
t.string :name
t.timestamps
end
end
end
- rake db:migrate
0
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.
0
I wasn’t able to make it work with migration script so I went ahead with this solution. Enter rails console using the terminal:
rails c
Type
ActiveRecord::Migration.drop_table(:tablename)
It works well for me. This will remove the previous table. Don’t forget to run
rails db:migrate
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.
3
Strange but it looks like I’m going to have to do this too.
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.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
andActiveRecord::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. `
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'"
0
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
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
Open you rails console
ActiveRecord::Base.connection.execute("drop table table_name")
0
ActiveRecord::Base.connection.drop_table :table_name
1
If you are working in a development environment this is a much easier solution than answers with more votes
if anybody is looking for how to do it in SQL.
type rails dbconsole
from terminal
enter password
In console do
USE db_name;
DROP TABLE table_name;
exit
Please dont forget to remove the migration file and table structure from schema
1
You can also open it by typing just
rails db
– ARK
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"
0
the best way you can do is
rails g migration Drop_table_Users
then do the following
rake db:migrate
0
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
In migration you can drop table by:
drop_table(table_name, **options)
options:
:force
Set to :cascade to drop dependent objects as well. Defaults to false
:if_exists
Set to true to only drop the table if it exists. Defaults to false
Example:
Create migration for drop table, for example we are want to drop
User
tablerails g migration DropUsers Running via Spring preloader in process 13189 invoke active_record create db/migrate/20211110174028_drop_users.rb
Edit migration file, in our case it is
db/migrate/20211110174028_drop_users.rb
class DropUsers < ActiveRecord::Migration[6.1] def change drop_table :users, if_exist: true end end
Run migration for dropping
User
tablerails db:migrate == 20211110174028 DropUsers: migrating =============================== -- drop_table(:users, {:if_exist=>true}) -> 0.4607s
You can’t simply run drop_table :table_name
, instead you can create an empty migration by running:
rails g migration DropInstalls
You can then add this into that empty migration:
class DropInstalls < ActiveRecord::Migration
def change
drop_table :installs
end
end
Then run rails db:migrate
in the command line which should remove the Installs table
The solution was found here
1
Let me know if you have any q’s, will try to answer asap
Drop Table/Migration
run:-
$ rails generate migration DropTablename
exp:- $ rails generate migration DropProducts
0
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
Run this command:-
rails g migration drop_table_name
then:
rake db:migrate
or if you are using MySql database then:
- login with database
show databases;
show tables;
drop table_name;
4
Does this answer add anything to the existing, accepted answer? If not, there’s no need to post this.
– Tom Lordthis creates an empty migration in rails 4.2, as already stated in the question itself.
This is EXACTLY what the OP originally tried…this answer should be removed
Adding a simple answer does not deserve to be downvoted. It still is relevant, I guess. Be kind to newer users please.
– ARK
If you want to delete the table from the schema perform below operation —
rails db:rollback
1
This command will only undo the last migrate command. If that command is the creation of the table, it will drop the table. But unless you then delete the migration file that creates it, it will be recreated the at the next
db:migrate
. Keeping your migrations in order to replicate elsewhere is important, especially if work has been done in the meantime. Usingdb:rollback
to change the final database layout is almost guaranteed to ruin many people’s work.
Since
rails generate migration
has command-line options for generating migration code for creating tables, adding or changing columns, etc., it would be nice if it also had an option for dropping a table — but it doesn’t. Sure, writing theup
part is simple — just calldrop_table
— but thedown
part, generating the table again, might not always be so simple, especially if the schema of the table in question has been changed by migrations after its initial creation. Maybe someone should suggest to the developers of Rails that adding such an option would be a good idea.@TeemuLeisti How about just copy and paste the current table definition from schema.rb? I do it this way all the time…
@João Soares: OK, I guess that works. However, it would be nice if the process could be automated, so that you could just give a
rake
migration-creation command, with the name of a table as a parameter, that would produce the neededup
anddown
functions.