web-dev-qa-db-ja.com

削除されたエンティティがクエリ結果に表示されるのはなぜですか?

ソフト削除の概念を実装しようとしています。

これが私のオブジェクトです:

_class Post extends Eloquent {

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

    ...
_

ソフト削除はオンです。

さて、投稿を「削除」すると、「deleted_at」タイムスタンプが取得されます。

description

問題は、検索するか、all()を使用して投稿を表示すると、そこにソフト削除されたアイテムが表示されることです。なにが問題ですか?

29
Sergey Sob

Eloquentを使用すると、ソフト削除機能が機能します。 query builderを使用して結果をクエリしている場合、最終的にはすべてのレコードがゴミ箱に移動され、ゴミ箱に移動されません。

Laravel 4の現在のドキュメントでは明確ではありませんが、soft deletedの概念は Eloquent ORM -ソフト削除 クエリビルダではなく、次のことのみを想定できます:ソフト削除はEloquent ORMでのみ機能します。

29
Rubens Mariuzzo

時々、雄弁や_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();
_
45
devo

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がnullで、色が赤の場合、色が青ORであるすべての車を返します。この他のクエリと同じ動作であり、問​​題をより明確に示しています。

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

この問題を回避するには、クロージャーを渡す「where」メソッドを変更する必要があります。そのように:

$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で、色が赤または青になる可能性があるすべての車を検索します。

32
Thiago Mata

私は同じ問題を抱えていましたが、ここでは何も助けませんでした。

私の問題はコンストラクトにあり、親コンストラクタを呼び出すのを忘れていました。

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

   //Rest of my code
}

それが誰かを助けることを願っています!

6
William Perron

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;
}

クエリするとき

$ banners = Banners :: where( 'status'、1)-> get();

ソフト削除されたデータは返されません。

0
RN Kushwaha

Laravel 5.2.44はwithoutTrashed()メソッドをSoftDeletingScopeに追加しました。たとえば、次のようなものを使用できます。

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