2013-08-04 2 views
23

Я пытаюсь реализовать концепцию мягкого удаления.Почему мягкие удаленные объекты появляются в результатах запроса?

Вот мой объект:

class Post extends Eloquent { 

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

    ... 

Soft удаления включена.

Теперь, если я удалить "пост, он получает«deleted_at»метки:

description

Проблема заключается в том, когда я ищу или просто использовать all() для отображения сообщения, мягкий удален появляются элементы. Что не так?

+1

Вы можете разместить код, в котором вы удаляете объекты, а также, где вы запрашиваете их для отображения на странице? – msturdy

+3

спасибо, я уже решил проблему ... Я использовал Fluent-запросы вместо Eloquent, это и стало причиной этого поведения –

+0

Для будущих посетителей: [прочитайте это, если вы используете 4.2] (https://laracasts.com/ Форум /? p = 1766-laravel-4-2-soft-deletes-issue/0) – zehelvion

ответ

20

soft deleting функция работает при использовании Eloquent. Если вы запрашиваете результаты с помощью query builder, вы, в конце концов, увидите все записи, которые были уничтожены, а не обработаны.

Не ясно, в настоящие время документов по Laravel 4, но, видя, что концепция мягкого удаления только появляется под Eloquent ORM - Soft Deleting, а не под Query Builder, мы можем только предполагать, что: мягкого удаления работает только с красноречивым ОРМОМ.

+0

Первоначально я думал, что мои разработчики использовали Eloquent, так как запросы, упомянутые сначала в названии модели, похожи на то, как понравились документы в Rloquent area Laravel так: SomeModel: join ('table2', 'column1', 'column2') , а запросы в документах QueryBuilder используют DB :: table, которые мы не использовали. Но если вы используете соединения с использованием такого синтаксиса, то он по-прежнему будет включать в себя данные softDeleted, поэтому мне пришлось мучительно добавлять -> whereNull ('table1.deleted_at') -> whereNull ('table2.deleted_at') в моих запросах (я хочу был альтернативный плагин SoftDeletes для размещения в отдельных таблицах/схемах архивации) – armyofda12mnkeys

0

Я использую

Post::all() 

Я прекрасно работает, я имею в виду, что не возвращает мягкие удаленные элементы (элементы, помеченные deleted_at временные метки). Я использую Laravel 4.

34

Иногда вы получаете таблицы записей soft deleted с get() даже с красноречивым и protected $softDelete = true;.

Таким образом, чтобы избежать этой проблемы, используйте

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

Например, этот запрос будет получать все строки, в том числе мягкие удалены.

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

Таким образом, правильный метод,

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

Существует маленькая хитрость, с помощью мягкого удаления таблиц и запросов в Laravel:

Когда мы создаем что-то вроде

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

Система выполняет что-то вроде этого:

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

Пока что так хорошо.Но, когда мы применяем метод «orWhere», что-то смешное происходит

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

Система будет выполнять что-то вроде этого:

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

Этот новый запрос будет возвращать все машины, где deleted_at равно нулю и цвет синий или если цвет красный, даже если значение deleted_at не равно нулю. Это одно и то же поведение этого другого запроса, то, что показать проблему более явно:

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

Чтобы уйти от этой проблемы, вы должны изменить «где» метод проходящего замыкание. Как что:

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

Затем система будет выполнять что-то вроде этого:

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

Этот последний запрос, поиск всех автомобилей, где deleted_at является нулевым, и где цвет может быть или красным или синим, как мы этого хотели.

+0

Это гораздо лучший и всеобъемлющий ответ. –

3

У меня была такая же проблема, и здесь ничего не помогло.

Моя проблема была в моей конструкции, я забыл вызвать родительский конструктор:

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

    //Rest of my code 
} 

Надежда, что кому-то помочь!