Eliminazione di tutti i record in una tabella del database


Risposte:


249

Se stai cercando un modo per farlo senza SQL, dovresti essere in grado di utilizzare delete_all.

Post.delete_all

o con un criterio

Post.delete_all "person_id = 5 AND (category = 'Something' OR category = 'Else')"

Vedi qui per maggiori informazioni.

I record vengono eliminati senza caricarli prima, il che lo rende molto veloce ma interromperà la funzionalità come la cache del contatore che dipende dal codice dei binari da eseguire al momento dell'eliminazione.


13
Vale la pena notare che se hai associazioni con: depend = =>: destroy o qualsiasi cosa che debba essere ripulita dopo la cancellazione, probabilmente vorrai Post.destroy_all, anche se è molto più lento. Vedi apidock.com/rails/ActiveRecord/Base/destroy_all/class
Michael Hellein,

Questa risposta presuppone che alla tabella sia associato un modello. L'OP non ha specificato questo: cosa succede se la tabella è una tabella di join?
Toby 1 Kenobi,

1
@BradWerth se è considerato da alcuni uno stile buono o cattivo, sto solo dicendo che è possibile che un db di Rails abbia tabelle che non sono ActiveRecordmodelli. La domanda si pone sull'eliminazione di record da una 'tabella' e sto solo indicando o il presupposto contenuto nella risposta.
Toby 1 Kenobi,

Ho la stessa domanda di @ Toby1Kenobi.
nbsamar,

30

Per cancellare via SQL

Item.delete_all # accepts optional conditions

Per eliminare chiamando il metodo di distruzione di ciascun modello (costoso ma assicura che vengano richiamati i callback)

Item.destroy_all # accepts optional conditions

Tutto qui


21

se si desidera svuotare completamente il database e non solo eliminare uno o più modelli ad esso collegati, è possibile:

rake db:purge

puoi anche farlo sul database di test

rake db:test:purge

5

Se intendi cancellare ogni istanza di tutti i modelli, userei

ActiveRecord::Base.connection.tables.map(&:classify)
  .map{|name| name.constantize if Object.const_defined?(name)}
  .compact.each(&:delete_all)

1
Preferisci selectogni volta che devi usare un'espressione if all'interno di un blocco, in questo modo eviti di dover concatenare il metodo compatto per rimuovere elementi nulli.
Sebastian Palma,

4
BlogPost.find_each(&:destroy)

Questo è ottimo per circostanze di scarsa memoria.
Epigene,

Questa è l'unica risposta che tiene conto del consumo di memoria.
Giovanni

2
Oddio, perché fare un giro per questo ... non ha senso. basta eliminare tutti i record ELIMINA DA tabella, Model.delete_all
Imnl

@John perché una singola query consuma più memoria di un ciclo di query?
Imnl,

@Imnl Ogni iterazione crea un'istanza di una nuova istanza del modello in questione in modo che possa elaborare i callback per il metodo di eliminazione.
John,

2

Se il tuo modello si chiama BlogPost, sarebbe:

BlogPost.all.map(&:destroy)

questo recupererà ogni singolo BlogPost e lo caricherà in un array Ruby prima di distruggerli.
hdgarrood,

Dipende dall'ORM. Datamapper non lo farebbe perché non stai richiedendo nulla su ciascun modello. Ed ecco uno stacktrace Mongoid che mostra che non seleziona alcun campo prima di distruggere ogni voce:MOPED: 127.0.0.1:27017 QUERY database=a_database collection=nothings selector={} flags=[:slave_ok] limit=0 skip=0 batch_size=nil fields=nil (0.3378ms)
stef

4
dato che è una domanda su rotaie e il richiedente non ha detto quale ORM sta usando, dovremmo assumere ActiveRecord
hdgarrood

2

Risposta più recente nel caso in cui si desideri eliminare tutte le voci in ogni tabella:

def reset
    Rails.application.eager_load!
    ActiveRecord::Base.descendants.each { |c| c.delete_all unless c == ActiveRecord::SchemaMigration  }
end

Maggiori informazioni sul eager_load qui .

Dopo averlo chiamato, possiamo accedere a tutti i discendenti di ActiveRecord::Basee possiamo applicare un delete_allsu tutti i modelli.

Si noti che ci assicuriamo di non cancellare la tabella SchemaMigration.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.