How to delete all data from all tables in Rails?

前端 未结 16 2388
情歌与酒
情歌与酒 2020-12-07 15:23

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

相关标签:
16条回答
  • 2020-12-07 16:00

    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
    
    0 讨论(0)
  • 2020-12-07 16:03

    This will work also for Rails 4

    (ActiveRecord::Base.connection.tables - ['schema_migrations']).each do |table|
        table.classify.constantize.destroy_all
    end
    
    0 讨论(0)
  • 2020-12-07 16:04

    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.

    0 讨论(0)
  • 2020-12-07 16:05

    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
    
    0 讨论(0)
  • 2020-12-07 16:07

    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
    
    0 讨论(0)
  • 2020-12-07 16:11

    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.

    0 讨论(0)
提交回复
热议问题