Почему в результатах запроса появляются мягкие удаленные объекты?
Я пытаюсь реализовать концепцию мягкого удаления.
Вот мой объект:
class Post extends Eloquent {
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'posts';
protected $softDelete = true;
...
Мягкое удаление включено.
Теперь, если я "удалю" сообщение, он получает отметку "deleted_at":
![description]()
Проблема заключается в том, что при поиске или просто использовании all()
для отображения сообщений появляются мягкие удаленные элементы. Что не так?
Ответы
Ответ 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.