1

I want to create a rake task in order to delete all records from a certain n number of tables and reset the values of the id column, so that when I create a new record it gets id 1.
Previous question Truncate table(s) with rails console is useful to get the job done for a single table (I would use delete_all in place of destroy_all if the task can be improved in performance):

Model.delete_all
ActiveRecord::Base.connection.execute("TRUNCATE #{table_name} RESTART IDENTITY")

If I need to truncate more than one table, say tables table1, table2, table3, is there any chance to use a single ActiveRecord connection such as:

Model1.delete_all
Model2.delete_all
Model3.delete_all
ActiveRecord::Base.connection.execute("TRUNCATE #{table1, table2, table3} RESTART IDENTITY")

and so avoid to establish multiple ActiveRecord connections like the example below?

Model1.delete_all
Model2.delete_all
Model3.delete_all
ActiveRecord::Base.connection.execute("TRUNCATE #{table1} RESTART IDENTITY")
ActiveRecord::Base.connection.execute("TRUNCATE #{table2} RESTART IDENTITY")
ActiveRecord::Base.connection.execute("TRUNCATE #{table3} RESTART IDENTITY")
Community
  • 1
  • 1
Asarluhi
  • 1,280
  • 3
  • 22
  • 43
  • 1
    even if you try using raw SQL, it requires complex query, check this SO thread http://stackoverflow.com/questions/15926826/truncate-multi-tables – Saiqul Haq Sep 18 '16 at 14:14
  • I might have found a solution in the Postgresql documentation: https://www.postgresql.org/docs/9.1/static/sql-truncate.html – Asarluhi Sep 18 '16 at 15:33

1 Answers1

1

Rails 6.0 add new method: truncate_tables

ActiveRecord::Base.connection.truncate_tables(:table1_name, :table2_name)

truncate_tables has not yet provided api documentation, it is essentially based on the truncate method

source code

  def truncate(table_name, name = nil)
    execute(build_truncate_statements(table_name), name)
  end

  def truncate_tables(*table_names) # :nodoc:
    return if table_names.empty?

    with_multi_statements do
      disable_referential_integrity do
        Array(build_truncate_statements(*table_names)).each do |sql|
          execute_batch(sql, "Truncate Tables")
        end
      end
    end
  end

Rails 6.1 has made adjustments to prevent mistakenly deleting migrate-related tables source code

  def truncate_tables(*table_names) # :nodoc:
    table_names -= [schema_migration.table_name, InternalMetadata.table_name]

    return if table_names.empty?

    with_multi_statements do
      disable_referential_integrity do
        statements = build_truncate_statements(table_names)
        execute_batch(statements, "Truncate Tables")
      end
    end
  end
Ray Baxter
  • 3,181
  • 23
  • 27
YaEvan
  • 660
  • 9
  • 12