Post.delete_all
を実行してすべての投稿を削除できますが、すべての投稿、コメント、ブログなどを削除したい場合はどうすればよいですか?
すべてのモデルを反復処理し、delete_all
メソッドを実行するにはどうすればよいですか?
rake db:reset
移行からテーブルを再作成します。
コメントで示唆されているように、それを行うためのより速い方法はあります(ただし、新しいrakeタスクを追加する必要があります)。
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
一連の移行をすべて実行することなく、テーブルを削除してから再作成する効果があります。
justテーブル行を削除するより速い方法は、TRUNCATEコマンドを使用することです。
他の回答の多くは、行の削除とテーブルの削除の違いを無視しているようです。テーブルを削除すると、テーブルのデータとスキーマが破壊されます。つまり、テーブルを再作成するには追加の手順が必要です。 Sean McLearyの答えは私が見た中で最高だったので、出発点としてそれを使いました。ただし、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
Rails 4.2.0.alphaのマスターブランチのActiveRecordに最近追加されました
https://github.com/Rails/rails/commit/e2f232aba15937a4b9d14bd91e0392c6d55be58d
これはRails 4
(ActiveRecord::Base.connection.tables - ['schema_migrations']).each do |table|
table.classify.constantize.destroy_all
end
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
シードファイル(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
は、ここでの仕事には多すぎます。これにより、データベースが完全に削除され、ゼロから再構築され、すべての移行などが実行されます。シードコマンドを実行する方が高速です。
ここでは、Stack Overflowで database_cleaner gem に言及していないので見逃しています。
データベースクリーナーは、Rubyでデータベースをクリーニングするための一連の戦略です。元のユースケースは、テスト中にクリーンな状態を確保することでした。各戦略は少量のコードですが、データベースでテストするすべてのRuby=アプリで通常必要とされるコードです。
「戦略」とは、切り捨て、取引、削除という意味です。
ActiveRecord、DataMapper、Sequel、MongoMapper、Mongoid、およびCouchPotatoがサポートされています。
Database Cleaner 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
アプリケーションまたはRails consoleで使用中にテーブルに触れずにデータのみを削除する場合:
Rails.application.eager_load!
ActiveRecord::Base.connection.disable_referential_integrity do
ApplicationRecord.descendants.each do |model|
model.delete_all
end
end
このコードを使用すると、モデルを手動で参照したり、外部キー制約を使用したりする必要がなくなります(disable_referential_integrityのおかげ)。
ApplicationRecord.descendantsは、ActiveRecord :: Base.descendantsとは異なり、真のアプリケーションモデルのみを返します(ApplicationRecord、schema_migrations、ar_internal_metadataはこれ以上ありません)。
これは古い質問であることは知っていますが、これは誰かに役立つかもしれないと思いました。これは、データベースからすべてのデータを消去する非常に高速な方法です。
_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)
ブロックの特定の仕様でこの手法を使用します。これは、データベースをパージ、移行、リセットするためのRails rakeタスクよりもはるかに高速で効率的です。
ところで:データベース側で外部キー制約を強制している場合、これはおそらく失敗するでしょう。
Rails 6では、Rails db:truncate_all
テーブルを削除せずにすべてのデータを削除します。
その後、dbをシードしたい場合は、Rails db:seed:replant
すべてのデータとシードデータベースを切り捨てる
私の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
データベースをクリーンな状態にします。
@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