Я могу сделать Post.delete_all
, чтобы удалить все мои сообщения, но что, если я хочу удалить все сообщения, комментарии, блоги и т.д.?
Как перебрать все мои модели и запустить метод delete_all
?
Я могу сделать Post.delete_all
, чтобы удалить все мои сообщения, но что, если я хочу удалить все сообщения, комментарии, блоги и т.д.?
Как перебрать все мои модели и запустить метод delete_all
?
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.
У вас может быть более тонкое управление с помощью:
rake db:drop:all
И затем создайте базу данных без выполнения миграции,
rake db:create:all
Затем запустите все ваши миграции,
rake db:migrate
Вы также можете сделать:
mysqladmin drop databasename
Если вы пытаетесь сделать это из кода вместо командной строки, скажем, из метода 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
Я предупреждаю вас: хотя и не очень быстро. Вы, безусловно, лучше проведете транзакционные тесты.
Если вы просто хотите начать новую работу с нового набора пустых таблиц, вы можете сначала убедиться, что у вас есть современное определение схемы в db/schema.rb:
rake db:schema:dump
а затем:
rake db:schema:load
который имеет эффект отбрасывания таблиц, а затем их повторного создания, без использования всей вашей батареи миграции.
Более быстрый способ просто удалить строки таблицы - использовать команду 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
rails db:purge
недавно был добавлен в ActiveRecord в основной ветке рельсов 4.2.0.alpha
https://github.com/rails/rails/commit/e2f232aba15937a4b9d14bd91e0392c6d55be58d
Вы можете перечислить все модели в файле 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 быстрее.
Принятый ответ с 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
Это будет работать и для Rails 4
(ActiveRecord::Base.connection.tables - ['schema_migrations']).each do |table|
table.classify.constantize.destroy_all
end
Если вы хотите удалить только данные, не касаясь таблиц, используя его внутри своего приложения или консоли 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).
Мы потеряли место в 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
# 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
Я знаю, что это старый вопрос, но я подумал, что это может кому-то помочь. Это очень быстрый способ очистки всех данных из базы данных.
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: Я уверен, что это, скорее всего, потерпит неудачу, если вы будете применять ограничения внешнего ключа на стороне базы данных.
Мои 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 был в чистом состоянии.
В Rails 6 вы можете сделать rails db:truncate_all
, чтобы удалить все данные, не удаляя таблицы.
Если после этого вы захотите заполнить свою базу данных, вы также можете сделать rails db:seed:replant
для усечения всех данных и базы данных.
Основываясь на ответе @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