Je peux faire Post.delete_all
pour supprimer tous mes messages, mais que se passe-t-il si je souhaite supprimer tous les messages, commentaires, blogs, etc.?
Comment puis-je parcourir tous mes modèles et exécuter la méthode delete_all
?
rake db:reset
Il recrée votre table à partir des migrations.
Comme suggéré dans les commentaires, un moyen plus rapide de le faire (mais vous devez ajouter une nouvelle tâche de rake) est:
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
Réponse copiée de: réponse le SO .
Vous pouvez avoir un contrôle plus fin avec:
rake db:drop:all
Et puis créer la base de données sans exécuter les migrations,
rake db:create:all
Puis lancez toutes vos migrations,
rake db:migrate
Vous pouvez aussi faire:
mysqladmin drop databasename
Si vous essayez de le faire depuis le code au lieu de la ligne de commande, par exemple avec une méthode Test::Unit::TestCase#teardown
, vous pouvez faire soit
class MyTest < Test::Unit::TestCase
def teardown
ActiveRecord::Base.subclasses.each(&:delete_all)
end
end
ou
class MyTest < Test::Unit::TestCase
def teardown
Rake::Task['db:reset'].invoke
end
end
Je vous préviens cependant: ni en particulier rapide. Vous êtes certainement mieux avec des tests transactionnels si vous le pouvez.
Si vous voulez simplement recommencer à zéro avec un nouvel ensemble de tables vides, vous devez d'abord vous assurer que vous avez une définition à jour du schéma dans db/schema.rb:
rake db:schema:dump
et alors:
rake db:schema:load
ce qui a pour effet de supprimer des tables, puis de les recréer, sans passer par toute votre batterie de migrations.
Un moyen plus rapide de juste supprimer des lignes de table consiste à utiliser la commande TRUNCATE.
Beaucoup d'autres réponses semblent ignorer la différence entre la suppression de lignes et la suppression d'un tableau. La suppression d'une table détruit les données et le schéma de la table; ce qui signifie que vous avez besoin d'étapes supplémentaires pour recréer les tables. La réponse de Sean McLeary était la meilleure que j'ai vue, alors je l'ai utilisée comme point de départ. Cependant, je pense qu'il est préférable de tirer parti de la commande TRUNCATE, car elle devrait être plus rapide et réinitialiser les clés à incrémentation automatique. De plus, utiliser map
au lieu de each
raccourcit un peu le code.
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
a récemment été ajouté à ActiveRecord dans la branche principale de Rails 4.2.0.alpha
https://github.com/Rails/rails/commit/e2f232aba15937a4b9d14bd91e0392c6d55be58d
Cela fonctionnera aussi pour Rails 4
(ActiveRecord::Base.connection.tables - ['schema_migrations']).each do |table|
table.classify.constantize.destroy_all
end
Réponse acceptée avec 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
Vous pouvez lister tous les modèles dans le fichier seed (seeds.rb), et simplement lancer
rake db:seed
Le fichier de départ ressemblerait alors à quelque chose comme ça:
Model1.delete_all
Model2.delete_all
Model3.delete_all
Model4.delete_all
Model5.delete_all
Model6.delete_all
Model7.delete_all
...
rake db:reset
est trop pour votre travail ici. Cela va complètement tuer votre base de données et la reconstruire à partir de zéro, en exécutant toutes les migrations, etc. Pour exécuter la commande de démarrage est plus rapide.
Nous avons été négligent ici à Stack Overflow pour ne pas mentionner le database_cleaner gem :
Database Cleaner est un ensemble de stratégies permettant de nettoyer votre base de données en Ruby . Le cas d'utilisation original était d'assurer un état de propreté pendant les tests. Chaque stratégie est une petite quantité de code, mais est le code qui est généralement nécessaire dans toute application Ruby c'est tester avec une base de données.
Par «stratégie», M. Mabey entend: troncature, transaction et suppression.
ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid et CouchPotato sont pris en charge.
Voici un extrait de code rapide du 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
Si vous souhaitez supprimer uniquement les données sans toucher aux tables tout en les utilisant dans votre application ou la console Rails:
Rails.application.eager_load!
ActiveRecord::Base.connection.disable_referential_integrity do
ApplicationRecord.descendants.each do |model|
model.delete_all
end
end
Avec ce code, vous n'avez pas à vous soucier de référencer manuellement vos modèles et/ou avec des contraintes de clé étrangère (grâce à disable_referential_integrity).
ApplicationRecord.descendants ne renvoie que des modèles d’application vrais contrairement à ActiveRecord :: Base.descendants (plus ApplicationRecord, schema_migrations et ar_internal_metadata).
Je sais que c'est une vieille question, mais j'ai pensé que cela pourrait être utile à quelqu'un. C'est un moyen très rapide de nettoyer toutes les données d'une base de données.
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
J'utilise cette technique dans certaines spécifications d'un bloc after(:all)
. Cette opération est beaucoup plus rapide et efficace que n’importe laquelle des tâches de ratissage de Rails pour le nettoyage, la migration et la réinitialisation de la base de données.
BTW: Je suis à peu près sûr que cela échouerait probablement si vous appliquiez des contraintes de clé étrangère du côté de la base de données.
Dans Rails 6, vous pouvez utiliser Rails db:truncate_all
pour supprimer toutes les données sans supprimer aucune table.
Si vous souhaitez utiliser votre base de données après cela, vous pouvez également utiliser Rails db:seed:replant
pour tronquer toutes les données et la base de données
Mes 50 centimes, pour le nettoyage de la base de données et la possibilité d'effectuer à nouveau des migrations (dans les cas où vous ne pouvez pas supprimer de base de données, par exemple 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")
Et maintenant, vous pouvez exécuter rake db:migrate
pour que votre base de données soit dans un état propre.
Sur la base de la réponse de @Vlad Zloteanu, voici une version permettant de supprimer toutes les tables tout en conservant les enregistrements utilisateur et les sessions de connexion, ainsi que des métadonnées. N'hésitez pas à adapter la liste des tableaux à vos besoins.
# 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