Подтвердить что ты не робот

Как удалить все данные из всех таблиц в Rails?

Я могу сделать Post.delete_all, чтобы удалить все мои сообщения, но что, если я хочу удалить все сообщения, комментарии, блоги и т.д.?

Как перебрать все мои модели и запустить метод delete_all?

4b9b3361

Ответ 1

rake db:reset 

Он воссоздает таблицу из миграций.

Как было предложено в комментариях, более быстрый способ сделать это (но вы должны добавить новую задачу рейка):

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

Ответ скопирован из: ответьте на SO.

Ответ 2

У вас может быть более тонкое управление с помощью:

rake db:drop:all

И затем создайте базу данных без выполнения миграции,

rake db:create:all

Затем запустите все ваши миграции,

rake db:migrate 

Вы также можете сделать:

mysqladmin drop databasename

Ответ 3

Если вы пытаетесь сделать это из кода вместо командной строки, скажем, из метода Test::Unit::TestCase#teardown, вы можете сделать либо

class MyTest < Test::Unit::TestCase

  def teardown
    ActiveRecord::Base.subclasses.each(&:delete_all)
  end

end

или

class MyTest < Test::Unit::TestCase

  def teardown
    Rake::Task['db:reset'].invoke
  end

end

Я предупреждаю вас: хотя и не очень быстро. Вы, безусловно, лучше проведете транзакционные тесты.

Ответ 4

Если вы просто хотите начать новую работу с нового набора пустых таблиц, вы можете сначала убедиться, что у вас есть современное определение схемы в db/schema.rb:

rake db:schema:dump

а затем:

rake db:schema:load

который имеет эффект отбрасывания таблиц, а затем их повторного создания, без использования всей вашей батареи миграции.

Ответ 5

Более быстрый способ просто удалить строки таблицы - использовать команду TRUNCATE.

Многие другие ответы, похоже, игнорируют разницу между удалением строк и откатом таблицы. Удаление таблицы разрушает данные таблицы и схему; что вам нужно сделать дополнительные шаги для воссоздания таблиц. Ответ Шона Мак-Лири был лучшим, что я видел, поэтому я использовал его в качестве отправной точки. Тем не менее, я думаю, что лучше использовать команду TRUNCATE, потому что она должна быть быстрее, а также сбрасывает ключи с автоматическим увеличением. Кроме того, использование map вместо each немного сокращает код.

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

Ответ 7

Вы можете перечислить все модели в файле seed (seeds.rb) и просто запустить

rake db:seed

Затем файл семени будет выглядеть примерно так:

Model1.delete_all
Model2.delete_all
Model3.delete_all
Model4.delete_all
Model5.delete_all
Model6.delete_all
Model7.delete_all

...

rake db:reset слишком много для вашей работы здесь. Это полностью уничтожит вашу базу данных и перестроит ее с нуля, выполнив все миграции и т.д. Для запуска команды seed быстрее.

Ответ 8

Принятый ответ с Postgres db:

namespace :db do
  desc "Truncate all tables"
  task :truncate => :environment do
    conn = ActiveRecord::Base.connection
    postgres = "SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname='public'"
    tables = conn.execute(postgres).map { |r| r['tablename'] }
    tables.delete "schema_migrations"
    tables.each { |t| conn.execute("TRUNCATE \"#{t}\"") }
  end
end

Ответ 9

Это будет работать и для Rails 4

(ActiveRecord::Base.connection.tables - ['schema_migrations']).each do |table|
    table.classify.constantize.destroy_all
end

Ответ 10

Если вы хотите удалить только данные, не касаясь таблиц, используя его внутри своего приложения или консоли rails:

Rails.application.eager_load!
ActiveRecord::Base.connection.disable_referential_integrity do
  ApplicationRecord.descendants.each do |model|
    model.delete_all
  end
end

С помощью этого кода вам не придется беспокоиться о том, чтобы вручную ссылаться на ваши модели и/или с ограничениями внешнего ключа (благодаря отключению_рефрактивности_интеграции).
ApplicationRecord.descendants возвращает только истинные модели приложений, в отличие от ActiveRecord:: Base.descendants(не более ApplicationRecord, schema_migrations и ar_internal_metadata).

Ответ 11

Мы потеряли место в Stack Overflow, не упоминая драгоценный камень database_cleaner:

Database Cleaner - это набор стратегий для очистки вашей базы данных в Ruby. Первоначальный вариант использования заключался в том, чтобы обеспечить чистое состояние во время испытаний. Каждая стратегия это небольшой код, но это код, который обычно требуется в любом приложении ruby который тестирует базу данных.

В соответствии с "стратегией" г-н Маби означает: усечение, транзакцию и удаление.

Поддерживаются ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid и CouchPotato.

Ниже приведен фрагмент кода из "Очистка базы данных README" :

require 'database_cleaner'
DatabaseCleaner.strategy = :truncation

# then, whenever you need to clean the DB
DatabaseCleaner.clean

Ответ 12

# fast truncation of all tables that need truncations (select is 10x faster then truncate)
# http://grosser.it/2012/07/03/rubyactiverecord-fastest-way-to-truncate-test-database/
def truncate_all_tables
  connection = ActiveRecord::Base.connection
  connection.disable_referential_integrity do
    connection.tables.each do |table_name|
      next if connection.select_value("SELECT count(*) FROM #{table_name}") == 0
      connection.execute("TRUNCATE TABLE #{table_name}")
    end
  end
end

Ответ 13

Я знаю, что это старый вопрос, но я подумал, что это может кому-то помочь. Это очень быстрый способ очистки всех данных из базы данных.

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

Я использую эту технику в определенных спецификациях в блоке after(:all). Это намного быстрее и эффективнее, чем любая из задач Rake Rake для очистки, миграции, перепродажи базы данных.

BTW: Я уверен, что это, скорее всего, потерпит неудачу, если вы будете применять ограничения внешнего ключа на стороне базы данных.

Ответ 14

Мои 50 центов за очистку db и возможность запуска миграции снова (в случаях, когда вы не можете удалить базу данных, например AWS RDS):

# get connection
conn = ActiveRecord::Base.connection
# find all tables needed to be removed
tables = conn.execute("SELECT * FROM pg_catalog.pg_tables WHERE schemaname='public' AND tablename<>'schema_migrations'").to_a.map { |r| r['tablename'] }
# remove all tables except schema_migrations
tables.each { |t| conn.execute("DROP TABLE #{t}") }
# clean migrations table
conn.execute("TRUNCATE TABLE schema_migrations")

И теперь вы можете запустить rake db:migrate, чтобы ваш db был в чистом состоянии.

Ответ 15

В Rails 6 вы можете сделать rails db:truncate_all, чтобы удалить все данные, не удаляя таблицы.

Если после этого вы захотите заполнить свою базу данных, вы также можете сделать rails db:seed:replant для усечения всех данных и базы данных.

Ответ 16

Основываясь на ответе @Vlad Zloteanu, вот версия для удаления всех таблиц, сохраняя записи пользователей и сеансы входа в систему вместе с некоторой метаинформацией. Не стесняйтесь настроить список таблиц в соответствии с вашими требованиями.

# 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