Como excluir todas as linhas de uma tabela usando o Eloquent?

135

Meu palpite era usar a seguinte sintaxe:

MyModel::all()->delete();

Mas isso não funcionou. Tenho certeza de que é super simples, mas procurei documentação sobre o assunto e não consigo encontrá-la!

Pete
fonte

Respostas:

279

O motivo MyModel::all()->delete()não funciona é porque, all()na verdade, dispara a consulta e retorna uma coleção de objetos Eloquent.

Você pode fazer uso do método truncado, isso funciona para o Laravel 4 e 5:

MyModel::truncate();

Isso elimina todas as linhas da tabela sem registrar exclusões de linhas individuais.

bilalq
fonte
1
Adicionei uma solução Laravel 3 à minha pergunta, para futuros leitores.
Pete
39
Agradável. Isso funciona no Laravel 5 também se alguém mais pesquisar no Google aqui em 2016.
samiles
14
Nota: truncate () também redefine qualquer balcão AUTO_INCREMENT (note também que puder tabelas não Truncar que têm restrições de chave estrangeira.)
William Turrell
10
FYI: Turncate não acionará eventos de exclusão.
Fusão
1
Se você realmente deseja usar MyModel::all()->delete(), useforeach (MyModel::all() as $e) { $e->delete() }
Ema4rl 2/17/17
70

Solução Laravel 5.2+ .

Model::getQuery()->delete();

Basta pegar o construtor subjacente com o nome da tabela e fazer o que for. Não poderia ser mais arrumado do que isso.

Solução Laravel 5.6

\App\Model::query()->delete();
Yauheni Prakopchyk
fonte
9
Caso alguém esteja confuso sobre o motivo disso funcionar, a classe Model encaminha os métodos para o Builder através do método mágico __call aqui . Como a própria classe model possui um método delete, chamar Model :: delete () chama o método Model, quando você realmente deseja o método Builder. Portanto, para obter o construtor explicitamente, você pode usar getQuery ().
precisa saber é o seguinte
Isso também não exclui tabelas relacionadas, se você desejar.
Terje Nesthus 22/09
Ele irá forçar excluir todos os registros, independentemente se é Excluir suaves ligado ou desligado
shalini
Model :: whereNotNull ('id') -> delete (); - vai fazer macia excluir quando suave delete é ON
shalini
61

Você pode usar Model::truncate()se desabilitar foreign_key_checks(presumo que você use o MySQL).

DB::statement("SET foreign_key_checks=0");
Model::truncate();
DB::statement("SET foreign_key_checks=1");
Fortex
fonte
2
No Laravel 4, você usa DB :: unprepared ()
swdev 15/01/14
você também pode usar Schema :: disableForeignKeyConstraints (); & Schema :: enableForeignKeyConstraints ();
Eleazar Resendez
33

Eu vi os dois métodos sendo usados ​​em arquivos de sementes.

// Uncomment the below to wipe the table clean before populating

DB::table('table_name')->truncate();

//or

DB::table('table_name')->delete();

Mesmo que você não possa usar o primeiro, se desejar definir chaves estrangeiras .

Não é possível truncar uma tabela referenciada em uma restrição de chave estrangeira

Portanto, pode ser uma boa ideia usar o segundo.

giannis christofakis
fonte
2
deleteobviamente não é o mesmo que truncatese.
Joel Mellon
2
@sudopeople Seria realmente útil apontar a diferença. Eu também poderia adicioná-lo à minha resposta .
Giannis christofakis
4
TRUNCATE não pode ser usado em uma transação, pois não é afetado pelo ROLLBACK. Nesse caso, isso pode ser alcançado com (novo MyModel) -> newQuery () -> delete ().
hammurabi
12

Existe uma maneira indireta:

myModel:where('anyColumnName', 'like', '%%')->delete();

Exemplo:

User:where('id', 'like' '%%')->delete();

Informações sobre o construtor de consultas do Laravel: https://laravel.com/docs/5.4/queries

Rejaul
fonte
1
@aschipfl não há muito o que explicar na verdade. O código executa o SQL DELETE FROM users WHERE id LIKE '%%'que corresponde a todas as linhas da tabela, excluindo tudo.
Hkan 23/11
Isso me colocou no meu caminho. Acabei fazendo um Arranque () em outro modelo para obter uma matriz de do ID que eu precisava, então usou essa matriz para excluir todos os registros de meu modelo usando o whereInmétodo: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC
9

Eu queria adicionar outra opção para aqueles que acessam esse tópico via Google. Eu precisava fazer isso, mas queria manter meu valor de incremento automático que é truncate()redefinido. Eu também não queria usar DB::nada porque queria operar diretamente fora do objeto de modelo. Então, eu fui com isso:

Model::whereNotNull('id')->delete();

Obviamente, a coluna terá que realmente existir, mas em um modelo Eloquent padrão e pronto para uso, a idcoluna existe e nunca é nula. Não sei se essa é a melhor escolha, mas funciona para meus propósitos.

lookitsatravis
fonte
Model::delete();realizará a mesma coisa.
Comp
5
Infelizmente, Model::delete()lança uma exceção Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically, pelo menos no Laravel 5.0.
Dave James Miller
6

Não fui capaz de usar Model::truncate(), pois seria um erro:

SQLSTATE [42000]: Erro de sintaxe ou violação de acesso: 1701 Não é possível truncar uma tabela referenciada em uma restrição de chave estrangeira

E infelizmente Model::delete()não funciona (pelo menos no Laravel 5.0):

O método não estático Illuminate \ Database \ Eloquent \ Model :: delete () não deve ser chamado estaticamente, assumindo $ this de um contexto incompatível

Mas isso funciona:

(new Model)->newQuery()->delete()

Isso excluirá todas as linhas automaticamente, se você tiver configurado a exclusão suave. Para excluir totalmente todas as linhas, incluindo as excluídas por software, você pode alterar para isso:

(new Model)->newQueryWithoutScopes()->forceDelete()
Dave James Miller
fonte
4

A melhor maneira de realizar essa operação Laravel 3parece ser o uso da Fluentinterface para truncar a tabela, como mostrado abaixo

DB::query("TRUNCATE TABLE mytable");
Pete
fonte
2

Você pode tentar este one-liner que preserva exclusões automáticas também:

Model::whereRaw('1=1')->delete();
jfeid
fonte
1

solução simples:

 Mymodel::query()->delete();
ali filali
fonte
0

De maneira semelhante à resposta de Travis vignon, eu exigi dados do modelo eloquente e, se as condições estivessem corretas, eu precisava excluir ou atualizar o modelo. Acabei obtendo o campo mínimo e máximo retornado pela minha consulta (caso outro campo fosse adicionado à tabela que atendesse aos meus critérios de seleção) junto com o critério de seleção original para atualizar os campos por meio de uma consulta SQL bruta (como oposta a uma consulta eloquente por objeto na coleção).

Eu sei que o uso de SQL bruto viola a filosofia de código de laravels, mas seria difícil suportar possivelmente centenas de consultas no lugar de uma.

Sidney
fonte
0

Pode fazer um laço também ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}
Sam Solomon
fonte
Tecnicamente sim ... mas o IMO parece um pouco desnecessário, pois existem melhores opções de consulta única.
Pete
@Pete eu sei .. outros já deram suas respostas ... eu estava tentando responder a outro método possível fazer ..
Sam Solomon
1
Isso realmente funciona para mim, pois planejo arquivar os modelos na coleção com base em regras específicas, mas também limpá-los dessa tabela ativa diariamente.
James Perih
-1

Solução que trabalha com o Lumen 5.5 com restrições de chaves estrangeiras:

$categories = MusicCategory::all();
foreach($categories as $category)
{
$category->delete();

}
return response()->json(['error' => false]);
Alain Berrier
fonte