2013-08-04 21 views
23

Sto cercando di implementare il concetto di eliminazione software.Perché le entità eliminate vengono visualizzate nei risultati della query?

Ecco il mio oggetto:

class Post extends Eloquent { 

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

    ... 

morbida di eliminazione è su.

Ora, se io 'eliminare' un post, diventa un 'deleted_at' timestamp:

description

Il problema è che quando faccio una ricerca o semplicemente usare all() per visualizzare i messaggi, il morbido cancellati gli articoli appaiono lì. Che c'è?

+1

è possibile inserire il codice in cui si eliminano gli oggetti e anche dove li si richiede di visualizzare nella pagina? – msturdy

+3

grazie, ho già risolto il problema ... stavo usando le query Fluent invece di Eloquent, questo era il motivo di questo comportamento –

+0

Per i futuri visitatori: [leggi questo se stai usando 4.2] (https://laracasts.com/ forum /? p = 1766-laravel-4-2-soft-deletes-issue/0) – zehelvion

risposta

20

L'opzione eliminazione graduale funziona quando si utilizza Eloquent. Se stai interrogando i risultati con il costruttore di query , vedrai tutti i record spostati nel cestino e non eliminati.

non è chiaro nella documentazione correnti di laravel 4, ma visto che il concetto di cancellazione morbida appare appena sotto Eloquent ORM - Soft Deleting e non sotto Query Builder, possiamo solo supporre che: morbido eliminare funziona solo con Eloquente ORM.

+0

Inizialmente pensavo che i miei sviluppatori usassero Eloquent poiché le query menzionavano il nome del modello come prima come i documenti di Eloquent di Laravel quindi: SomeModel: join ('table2', 'column1', 'column2') e le query nei documenti di QueryBuilder hanno utilizzato DB :: table specificamente che non stavamo usando. Ma se usi i join usando questo tipo di sintassi, includerà comunque i dati softDeleted, quindi ho dovuto aggiungere dolorosamente -> whereNull ('table1.deleted_at') -> whereNull ('table2.deleted_at') nelle mie query (vorrei c'era un plug-in SoftDeletes alternativo da inserire in tabelle/schemi di archiviazione separati) – armyofda12mnkeys

0

Io uso

Post::all() 

mi funziona bene, voglio dire che non restituisce gli elementi morbidi eliminati (gli elementi contrassegnati con deleted_at timestamp). Sto usando Laravel 4.

34

A volte, si ottengono le voci di tabella soft deleted con get() anche con eloquente e protected $softDelete = true;.

Quindi, per evitare questo problema, utilizzare

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

Ad esempio, la query verrà recuperato tutte le righe comprese morbido cancellato.

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

Quindi il metodo corretto è,

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

C'è un piccolo trucco utilizzando morbido eliminare le tabelle e query in laravel:

Quando creiamo qualcosa di simile

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

Il sistema esegue qualcosa del genere:

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

Finora, tutto bene.Ma, quando applichiamo il metodo "orWhere", qualcosa di divertente succede

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

Il sistema eseguirà una cosa del genere:

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

Questa nuova query restituirà tutte le auto in cui deleted_at è nullo e la il colore è blu OPPURE se il colore è rosso, anche se delete_at non è nullo. E 'lo stesso comportamento di questa altra domanda, quello che mostrano il problema in modo più esplicito:

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

di fuggire da questo problema, è necessario modificare il metodo di "dove" il superamento di un chiusura. Come quella:

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

Quindi, il sistema eseguirà una cosa del genere:

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

Questa ultima query, ricerche per tutte le auto in cui deleted_at è nullo e dove il colore può essere rosso o blu, come volevamo che lo facesse.

+0

Questa è una risposta molto migliore e completa. –

3

Ho avuto lo stesso problema e nulla qui mi ha aiutato.

Il mio problema è stato nel mio costrutto, ho dimenticato di chiamare il costruttore genitore:

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

    //Rest of my code 
} 

speranza che aiutare qualcuno!

Problemi correlati