web-dev-qa-db-fra.com

Pourquoi les entités supprimées de manière douce apparaissent dans les résultats de la requête?

J'essaie d'implémenter le concept de suppression douce.

Voici mon objet:

class Post extends Eloquent {

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'posts';
    protected $softDelete = true;

    ...

La suppression logicielle est activée.

Maintenant, si je "supprime" un message, il obtient un horodatage "supprimé":

description

Le problème est que, lorsque je recherche ou utilise simplement all() pour afficher les publications, les éléments supprimés disparaissent. Qu'est-ce qui ne va pas?

27
Sergey Sob

La fonction suppression douce fonctionne avec Eloquent. Si vous interrogez les résultats avec query builder, tous les enregistrements seront éventuellement supprimés et non supprimés.

Ce n'est pas clair dans la documentation actuelle de Laravel 4, mais vu que le concept de suppression douce apparaît uniquement sous ORM Eloquent - Suppression douce et non sous Query Builder, nous pouvons simplement supposer que: la suppression logicielle ne fonctionne qu'avec Eloquent ORM.

25
Rubens Mariuzzo

Parfois, vous obtiendrez les entrées de la table soft deleted avec get() même avec éloquent et protected $softDelete = true;.

Donc, pour éviter ce problème, utilisez

...->whereNull('deleted_at')->get();

Par exemple, cette requête va extraire toutes les lignes, y compris les logiciels supprimés.

DB::table('pages')->select('id','title', 'slug')
                                   ->where('is_navigation','=','yes')
                                   ->where('parent_id','=',$parent_id)
                                   ->orderBy('page_order')
                                   ->get();

Donc, la bonne méthode est,

DB::table('pages')->select('id','title', 'slug')
                                   ->where('is_navigation','=','yes')
                                   ->where('parent_id','=',$parent_id)
                                   ->whereNull('deleted_at')
                                   ->orderBy('page_order')
                                   ->get();
42
devo

Il existe un petit truc utilisant les tables de suppression logicielles et les requêtes dans laravel:

Quand on crée quelque chose comme

$objCars = Car::where("color","blue");

Le système exécute quelque chose comme ça:

SELECT
  *
FROM
  cars
WHERE
  deleted_at IS NULL
AND
  "color" = 'blue'

Jusqu'ici tout va bien. Mais, lorsque nous appliquons la méthode "ou Où", quelque chose de drôle se produit

$objCars = Car::where("color","blue")->orWhere("color","red");

Le système va exécuter quelque chose comme ça:

SELECT 
  * 
FROM
  cars
WHERE
  deleted_at IS NULL 
AND 
  "color" = 'blue'
OR
  "color" = 'red'

Cette nouvelle requête retournera toute la voiture où delete_at a la valeur null et la couleur est bleue OR si la couleur est rouge, même si la valeur delete_at n'est pas nulle. C'est le même comportement de cette autre requête, ce qui montre le problème plus explicitement:

SELECT 
  * 
FROM
  cars
WHERE
  (
    deleted_at IS NULL 
  AND 
    "color" = 'blue'
  )
OR
  "color" = 'red'

Pour échapper à ce problème, vous devez changer la méthode "where" en passant une fermeture. Comme ça:

$objCars = Car::where(
  function ( $query ) {
    $query->where("color","blue");
    $query->orWhere("color","red");
  }
);

Ensuite, le système exécutera quelque chose comme ça:

SELECT
  *
FROM
  cars
WHERE
  deleted_at IS NULL
AND
  (
    "color" = 'blue' 
  OR
    "color" = 'red'
  )

Cette dernière requête recherche toutes les voitures pour lesquelles delete_at a la valeur null et où la couleur peut être rouge ou bleue, comme nous le souhaitions.

30
Thiago Mata

J'ai eu le même problème et rien ici ne m'a aidé.

Mon problème était dans ma construction, j'ai oublié d'appeler le constructeur parent:

public function __construct()
{
   parent::__construct();

   //Rest of my code
}

J'espère que ça aide quelqu'un!

4
William Perron

Testé dans Laravel 5.6, vous devez utiliser SoftDeletes Trait dans votre modèle.

utilisez Illuminate\Database\Eloquent\SoftDeletes;

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Banners extends Model
{
    use SoftDeletes;
    //no need of this below line
    //protected $softDelete = true;
}

et quand vous interrogez

$ banners = Banners :: where ('status', 1) -> get ();

il ne retournera pas les données supprimées par logiciel.

0
RN Kushwaha