Подтвердить что ты не робот

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

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

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

class Post extends Eloquent {

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

    ...

Мягкое удаление включено.

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

description

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

4b9b3361

Ответ 1

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

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

Ответ 2

Иногда вы получаете записи таблицы 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();

Ответ 3

Есть небольшой трюк с использованием таблиц и запросов для мягкого удаления в 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 имеет значение NULL, а цвет - синий или если цвет красный, даже если значение deleted_at не равно нулю. Это то же поведение этого другого запроса, что явно показывает проблему:

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

Чтобы избежать этой проблемы, вы должны изменить метод "where", проходящий через Closure. Например:

$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 имеет значение NULL и где цвет может быть или красным или синим, как мы этого хотели.

Ответ 4

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

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

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

   //Rest of my code
}

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

Ответ 5

Протестировано в Laravel 5.6. Вам нужно использовать SoftDeletes Trait в вашей модели

использовать 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;
}

и когда вы запрашиваете

$ banner = Banners :: where ('status', 1) → get();

он не вернет мягко удаленные данные.

Ответ 6

В Laravel 5.2.44 добавлен withoutTrashed() для SoftDeletingScope. Например, вы можете использовать что-то вроде этого:

Post::withoutTrashed()->get();

Ответ 7

Я использую

Post::all()

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