Почему мягко удаленные объекты появляются в результатах запроса?
Я пытаюсь реализовать концепцию мягкого удаления.
Вот мой объект:
class Post extends Eloquent {
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'posts';
protected $softDelete = true;
...
Мягкое удаление включено.
Теперь, если я "удаляю" сообщение, оно получает метку времени
Проблема в том, когда я ищу или просто использую all()
чтобы отобразить сообщения, там отображаются мягкие удаленные элементы. Что случилось?
8 ответов
Функция мягкого удаления работает при использовании Eloquent. Если вы запрашиваете результаты с помощью построителя запросов, вы в конечном итоге увидите, что все записи уничтожены, а не уничтожены.
Это неясно в текущих документах Laravel 4, но, видя, что концепция мягкого удаления появляется только в Eloquent ORM - Мягкое удаление, а не в Query Builder, мы можем только предположить, что: мягкое удаление работает только с Eloquent ORM.
Иногда вы получите 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();
Есть небольшой трюк с использованием таблиц мягкого удаления и запросов в 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'
Этот новый запрос вернет всю машину, в которой удаленный_элемент равен нулю, а цвет - синий ИЛИ, если цвет красный, даже если удаленный_кат не равен нулю. Это то же самое поведение этого другого запроса, что показывает проблему более явно:
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'
)
В этом последнем запросе выполняется поиск всех автомобилей, для которых в поле delete_at указано значение NULL, а цвет может быть либо красным, либо синим, как мы и хотели.
У меня была такая же проблема, и здесь мне ничего не помогло.
Моя проблема была в моей конструкции, я забыл вызвать родительский конструктор:
public function __construct()
{
parent::__construct();
//Rest of my code
}
Надеюсь, что помочь кому-то!
Добавлен Laravel 5.2.44 withoutTrashed()
способ SoftDeletingScope
. Например, вы можете использовать что-то вроде этого:
Post::withoutTrashed()->get();
Протестировано в 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();
он не вернет мягко удаленные данные.
Я использую
Post::all()
Я отлично работаю, я имею в виду, что он не возвращает мягкие удаленные элементы (элементы, помеченные с помощью меток времени удаленных_данных) Я использую Laravel 4.
я решил объединить таблицу с красноречивым на softdelete - laravel 8
$query = Model_table_1::join('user', 'user.id', '=', 'table_1.user_id')
->join('table_2', 'table_2.id', '=', 'table_1.table2_id')
->join('table_3', 'table_3.id', '=', 'table_1.table3_id')
->join('table_4', 'table_4.id', '=', 'table_3.table4_id')
->select('table_1.id','table_1.name','table_1.created_at',
'user.name','table_2.name2','table_3.name3','table_4.name4')
->get();
использовать где в datatables
$query = Model_table_1::join('user', 'user.id', '=', 'table_1.user_id')
->join('table_2', 'table_2.id', '=', 'table_1.table2_id')
->join('table_3', 'table_3.id', '=', 'table_1.table3_id')
->join('table_4', 'table_4.id', '=', 'table_3.table4_id')
->select('table_1.id','table_1.name','table_1.created_at','user.name','table_2.name2','table_3.name3','table_4.name4')
->where('table_1.user_id', '=', Auth::user()->id)
->get();
использовать там, где видно
$query = Model_table_1::join('user', 'user.id', '=', 'table_1.user_id')
->join('table_2', 'table_2.id', '=', 'table_1.table2_id')
->join('table_3', 'table_3.id', '=', 'table_1.table3_id')
->join('table_4', 'table_4.id', '=', 'table_3.table4_id')
->select('table_1.id','table_1.name','table_1.created_at','user.name','table_2.name2','table_3.name3','table_4.name4')
->where('table_1.user_id', '=', Auth::user()->id)
->first();