2017-12-11 10 views
0

私は3つのモデルがあるとしましょう:ParentChildGrandChildです。親hasMany()子供、子供hasMany()グランドチャイルド。今度は私が->delete()親モデルを使用すると、子モデルとGrandChildモデルは影響を受けません。しかし、私はまた、関連するモデルを削除したい。私は私のコントローラのdestroy()方法でこれをやってみました:ラーベルモデル削除階層

$parent->childs->grandchilds()->delete(); 
$parent->childs()->delete(); 
$parent->delete(); 

が、それは私がChildモデルのhasMany()関係を設定しているにもかかわらず、存在しないgrandchilds()BadMethodCallException、方法をスローします。

外部キー制約を設定することなく、関連するすべてのモデルをうまく削除するにはどうすればよいですか?アプリケーションには3つ以上の関連するモデルが存在するため、この時点ですべての移行ファイルが非常に時間がかかります。例えば

答えて

0

あなたが->grandchilds()->delete()を呼び出しているので、それは動作しませんしようとした道クエリビルダまたはモデルではなく、childsのコレクションにあります。

foreach($parent->childs as $child){ 
    $child->grandchilds()->delete(); // Here you call it on a query builder (relationship) 
    $child->delete(); // Here you call it on a model 
} 
$parent->delete(); // Calling on a model 

それとも->hasManyThrough(Child, GrandChild)関係を設定し、あなたは関係なく、3つのクエリをのみが必要になりますから、よりパフォーマンスも(そのように削除できます:

一つの方法は、子供に対するforeachことであろう子供の数):

$parent->grandchilds()->delete(); // Assumed the name of hasManyThrough relationship to be "grandchilds" 
$parent->childs()->delete(); 
$parent->delete(); 
+0

もし私が一層深くする必要があるならば(あるいは後のある時点で)、どうすればhasManyThroughを設定できますか?さて、私は 'GreatGrandChild'モデルを持っているとしましょう。 – Eisenheim

+0

''削除カスケード 'なしでそれを行う良い方法はありません。外来の鍵はあなたの親友です。長期的には時間を節約し、パフォーマンスを向上させます。 – devk

3

セットアップforeign key constraints with ->onDelete('cascade')、:

$table->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade'); 

孫の移行に同じ操作を行います。

この場合、親モデルを削除すると、関連するすべての子と孫がautomatically deleted by DBになります。アレクセイにより示唆されるように、あなたがカスケードを実装することはできません何らかの理由で削除された場合

+1

これは絶対にそれが行われるべき方法ですが、アスカーは、特に外部キー制約に私はその部分を見逃している – devk

+0

@devkを設定しなくても>言いました。この場合、OPは間違いなくあなたの答えのコードを使用する必要があります。 –

0

、あなたはこれを達成するために、ループを使用することができます。

foreach($parent->childs AS $child){ 
    foreach($child->grandchilds AS $grandchild){ 
    $grandchild->delete(); 
    } 
    $child->delete(); 
} 
$parent->delete();