2017-03-13 7 views
2

私のdeleteメソッドは、このようなものです:売り手は削除した場合雄弁のモデルの条件を作成するには? (Laravel 5.3)コントローラ上の

:私はこれが好きたかった

<?php 
namespace App\Models; 
use Jenssegers\Mongodb\Eloquent\Model as Eloquent; 
use Jenssegers\Mongodb\Eloquent\HybridRelations; 
use Jenssegers\Mongodb\Eloquent\SoftDeletes; 
class MessageThread extends Eloquent 
{ 
    use HybridRelations; 
    use SoftDeletes; 
    // const DELETED_AT = 'deleted_by_seller'; 
    // const DELETED_AT = 'deleted_by_buyer'; 
    protected $connection = 'mongodb'; 
    protected $dates = ['deleted_by_seller', 'deleted_by_buyer']; 
    protected $fillable = ['subject', 'information', 'created_at', 'update_at']; 
} 

<?php 
public function deleteMessage($id, $seller_id, $buyer_id) 
{ 
    //if the seller delete 
    if($seller_id == auth()->user->id) 
     //const DELETED_AT = 'deleted_by_seller'; 
    //if the buyer delete 
    else($buyer_id == auth()->user->id) 
     //const DELETED_AT = 'deleted_by_buyer'; 

    $result = Message::destroy($id); 
    return $result; 
} 

私のモデルは、このようなものですメッセージ:const DELETED_AT = 'deleted_by_seller';

購入者がメッセージを削除した場合:const DELETED_AT = 'deleted_by_buyer';

どうすればいいですか?

答えて

1

まず、あなたが持っている理想的なDB構造ではないと思います。 deleted_by_sellerとdeleted_by_buyerを含める代わりに、2つの列、deleted_byとdeleted_atを持たなければなりません。お使いのコントローラで

protected $deletedAtCol = "deleted_at"; 

/** 
* Get the name of the "deleted at" column. 
* 
* @return string 
*/ 
public function getDeletedAtColumn() 
{ 
    return $this->deletedAtCol; 
} 

/** 
* Set the name of the "deleted at" column. 
* @param string $colName 
* @return string 
*/ 
public function setDeletedAtColumn($colName) 
{ 
    $this->deletedAtCol = $colName; 
} 

その後:

あなたはまだ@Williamが指摘したように、このしようと、既存のDB構造を進めて行きたい場合は、次を追加し、あなたのモデルクラスで

を、これを追加してください:

public function deleteMessage($id, $seller_id, $buyer_id) 
{ 
    $message = Message::findOrFail($id); 
    //if the seller delete 
    if($seller_id == auth()->user->id) 
     $message->setDeletedAtCol("deleted_by_seller"); 
    //if the buyer delete 
    else($buyer_id == auth()->user->id) 
     $message->setDeletedAtCol("deleted_by_buyer"); 

    return $message->delete(); 
} 
+0

あなたは正しい答えを持っているようです。やってみます。ありがとう –

+0

あなたの方法を使用する場合、それは2つの列:deleted_byとdeleted_atを使用しています。 deleted_byをどのように埋めることができますか?削除された場合は、すでに自動的に入力されています –

+0

その方法の場合、モデルイベントを使用することができます:https://laravel.com/docs/5.4/eloquent#events – Paras

3

更新:

オリジナルの記事はlaravelでは私のpersonal blog

SoftDeletes形質

を意味し、我々はIlluminate\Database\Eloquent\Modelを拡張することにより、当社の独自のモデルを定義します。モデルインスタンスを柔らかく削除するには、モデルでIlluminate\Database\Eloquent\SoftDeletesの特性を使用する必要があります。 runSoftDelete()は、SoftDeletesの主要な機能であり、レコードが削除されたかどうかを示すために使用される列を取得し、現在のタイムスタンプで列を更新します。

protected function runSoftDelete() 
{ 
    $query = $this->newQueryWithoutScopes()->where($this->getKeyName(), $this->getKey()); 
    $this->{$this->getDeletedAtColumn()} = $time = $this->freshTimestamp(); 
    $query->update([$this->getDeletedAtColumn() => $this->fromDateTime($time)]); 
} 

削除の手順()

私たちはモデルにdelete()関数を呼び出すときはどうなりますか?

私たち自身のモデルはIlluminate\Database\Eloquent\Modelを拡張しているので、それを一目瞭然にします。 delete()関数は次のとおりです。

public function delete() 
{ 
    if (is_null($this->getKeyName())) { 
     throw new Exception('No primary key defined on model.'); 
    } 

    if ($this->exists) { 
     if ($this->fireModelEvent('deleting') === false) { 
      return false; 
     } 

     // Here, we'll touch the owning models, verifying these timestamps get updated 
     // for the models. This will allow any caching to get broken on the parents 
     // by the timestamp. Then we will go ahead and delete the model instance. 
     $this->touchOwners(); 

     $this->performDeleteOnModel(); 

     $this->exists = false; 

     // Once the model has been deleted, we will fire off the deleted event so that 
     // the developers may hook into post-delete operations. We will then return 
     // a boolean true as the delete is presumably successful on the database. 
     $this->fireModelEvent('deleted', false); 

     return true; 
    } 
} 

コードは明確です。これは、モデルがprimaryKeyであり、インスタンスがデータベースに最初に存在することを保証します。その後、削除操作を実行するためにperformDeleteOnModel()関数を呼び出します。注意が必要です!

ここで私たちが知っている必要があります。

Anは基本クラスからメンバを継承は形質によって挿入されたメンバーによって上書きされます。優先順位は、現在のクラスのメンバーがTraitメソッドをオーバーライドし、継承されたメソッドをオーバーライドすることです。

呼ばperformDeleteOnModel()が同じSoftDeletes特性に名前はなくModelクラスの1を有するものであるときに、正確な関数が実行されます。そして今、我々は形質に引き返す:

protected function performDeleteOnModel() 
{ 
    if ($this->forceDeleting) { 
     return $this->newQueryWithoutScopes()->where($this->getKeyName(), $this->getKey())->forceDelete(); 
    } 

    return $this->runSoftDelete(); 
} 

まあ、それは我々が最初に話しましたrunSoftDelete()を呼び出します。そして、これは柔らかいdetetionの手順です。アスカー

の取得に

問題は、削除時に異なるDELETED_AT列を使用したいと考えています。 getDeletedAtColumn()をオーバーライドするだけで、ソフト削除メカニズムをうまく機能させることが望まれます。削除されたモデルがソフトで削除されても、まだ結果に残っているのはなぜですか?

Modelクラスが構築されると、それは彼らのboot[TraitName]メソッドを呼び出すことによって特性を起動します。したがって、ここにはbootSoftDelete()メソッドがあります。

protected static function bootTraits() 
{ 
    foreach (class_uses_recursive(get_called_class()) as $trait) { 
     if (method_exists(get_called_class(), $method = 'boot'.class_basename($trait))) { 
      forward_static_call([get_called_class(), $method]); 
     } 
    } 
} 

ここでもうSoftDeletes形質に注目しましょう。ここ

public static function bootSoftDeletes() 
{ 
    static::addGlobalScope(new SoftDeletingScope); 
} 

形質はstatic::addGlobalScope()を呼び出してapply()方法を有するSoftDeletingScopeクラスを登録します。 Modelクラスにあるメソッドは、$globalScopes配列に格納します。

public static function addGlobalScope(ScopeInterface $scope) 
{ 
    static::$globalScopes[get_called_class()][get_class($scope)] = $scope; 
} 

クエリがモデル上に構築されて

は、applyGlobalScopes()方法は$globalScopes配列一つずつとそのapply()メソッドを呼び出し内のインスタンスを訪問し、自動的に呼び出されます。

public function applyGlobalScopes($builder) 
{ 
    foreach ($this->getGlobalScopes() as $scope) { 
     $scope->apply($builder, $this); 
    } 

    return $builder; 
} 

今問題のベールを持ち上げます。 SoftDeletingScopeクラスでは:

public function apply(Builder $builder, Model $model) 
{ 
    $builder->whereNull($model->getQualifiedDeletedAtColumn()); 

    $this->extend($builder); 
} 

それは、そのDELETED_AT列nullであるそれらのレコードを選択するために、すべてのクエリに制約を追加します。そしてこれはSoftDeletesの秘密です。

ダイナミックDELETED_AT列まず

、私は、ダイナミックDELETED_AT列を使用して、このような行動をお勧めしていないことを再確認する必要があります。

ダイナミックDELETED_AT列のアスカーの問題を解決するために、あなたは、このようなapply()機能を使用して独自のSoftDeletingScopeクラスを実装する必要があります。

public function apply(Builder $builder, Model $model) 
{ 
    $builder->where(function ($query){ 
     $query->where('DELETED_AT_COLUMN_1',null)->orWhere('DELETED_AT_COLUMN_2',null); 
    }); 

    $this->extend($builder); 
} 

そしてそれ

public static function bootSoftDeletes() 
{ 
    static::addGlobalScope(new YourOwnSoftDeletingScope); 
} 

オリジナルでbootSoftDeletes()をオーバライド答え:

の値を変更することはできません。実行時の変数。したがって、CREATED_ATの値を手動で割り当てる必要があります。

+0

解決策はありませんか?それは特定の条件に基づいてそれを変更する必要があるので –

+0

あなたはドンを強く主張する場合。モデルの 'getDeletedAtColumn'メソッドをオーバーライドすることができます。モデルを破壊するたびに、 'SoftDeletes'はこのメソッドを呼び出して、変更する必要のある列を取得します。 –

+0

私はまだ混乱しています。あなたはもっと詳しく解答してください。 –