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

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

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

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();
Другие вопросы по тегам