I can do Post.delete_all
to delete all my posts, but what if I want to delete all posts, comments, blogs, etc.?
How do I iterate over all my models and
A faster way to just delete table rows is to use the TRUNCATE command.
Many of the other answers seem to ignore the difference between deleting rows and dropping a table. Dropping a table destroys the table data and schema; meaning that you need extra steps to recreate the tables. Sean McLeary's answer was the best I saw, so I used it as a starting point. However, I think it is better to take advantage of the TRUNCATE command, because it should be faster and it also resets auto-increment keys. Also, using map
instead of each
shortens the code a bit.
namespace :db do
desc "Truncate all tables"
task :truncate => :environment do
conn = ActiveRecord::Base.connection
tables = conn.execute("show tables").map { |r| r[0] }
tables.delete "schema_migrations"
tables.each { |t| conn.execute("TRUNCATE #{t}") }
end
end
This will work also for Rails 4
(ActiveRecord::Base.connection.tables - ['schema_migrations']).each do |table|
table.classify.constantize.destroy_all
end
I know this is an old question, but I thought this might be helpful to someone. This is a very fast way of cleaning out all data from a database.
tables = []
ActiveRecord::Base.connection.execute("show tables").each { |r| tables << r[0] }
tables = tables - ["schema_migrations"]
tables.each do |table|
ActiveRecord::Base.connection.execute("DELETE FROM #{table} WHERE 1 = 1")
end
I use this technique in certain specs in an after(:all)
block. This is much faster and more efficient than any of the Rails rake tasks for purging, migrating, reseting the database.
BTW: I'm pretty sure this would likely fail if you were enforcing foreign key constraints on the database side.
We have been remiss here at Stack Overflow for not mentioning the database_cleaner gem:
Database Cleaner is a set of strategies for cleaning your database in Ruby. The original use case was to ensure a clean state during tests. Each strategy is a small amount of code but is code that is usually needed in any ruby app that is testing with a database.
By 'strategy', Mr. Mabey means: truncation, transaction, and deletion.
ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, and CouchPotato are supported.
Here is a quick code snippet from the Database Cleaner README:
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
# then, whenever you need to clean the DB
DatabaseCleaner.clean
Building up on @Vlad Zloteanu's answer, here is a version to remove all tables while keeping the user records and login sessions together with some meta information. Feel free to adjust the list of tables to your requirements.
# lib/tasks/db/truncate.rake
namespace :db do
desc 'Truncate all tables except users state and meta'
task truncate: :environment do
conn = ActiveRecord::Base.connection
tables = conn.tables - %w[
sessions
users
roles
users_roles
schema_migrations
ar_internal_metadata
]
tables.each { |t| conn.execute("TRUNCATE #{t}") }
puts "Truncated tables\n================\n#{tables.sort.join("\n")}"
end
end
If you're trying to do this from code instead of the command line, say from a Test::Unit::TestCase#teardown
method, you could do either
class MyTest < Test::Unit::TestCase
def teardown
ActiveRecord::Base.subclasses.each(&:delete_all)
end
end
or
class MyTest < Test::Unit::TestCase
def teardown
Rake::Task['db:reset'].invoke
end
end
I warn you, though: neither is particularly fast. You're definitely better off with transactional tests if you can.