2016-09-13 15 views
0

これをアプローチする方法が本当にわからないが、私はしたentry_id(外部キー)と、このようなキー/値のメタテーブルがあります。私は、キー/値の新しいリストをentry_id 4を更新するLaravel 5 - firstOrCreate()および古いアイテムを削除しますか?

id | entry_id |  key  |  value  
------------------------------------------- 
1  4   Fruit 1  Apple 
2  4   Fruit 2  Banana 
3  4   Fruit 3  Cantaloupe 

を次のようになりペアFruit 1/AppleFruit 4/Dragonfruit、:だからここ

id | entry_id |  key  |  value  
------------------------------------------- 
1  4   Fruit 1  Apple 
4  4   Fruit 4  Dragonfruit 

は起こるべき3つの事です:

  • Fruit 1/Appleは変更されていないため、同じままにしてください。
  • Fruit 4/Dragonfruitは新しいものですので、追加する必要があります。
  • 新しい更新リストにはFruit 2/BananaまたはFruit 3/Cantaloupeが含まれていないため、削除する必要があります。

は、私はこのようなfirstOrCreate()を使用してみました:

起こるべき3つの事の最初の2箇条書きの世話を
// $metas is an array of the new list 
foreach ($metas as $meta) { 
    $entry->entryMeta()->firstOrCreate([ 
    'entry_id' => $entry->id, 
    'key' => $meta->key, 
    'value' => $meta->value 
    ]); 
} 

。新しいリストに含まれていない古いアイテムを削除する最後の箇条書きは機能しません(これはfirstOrCreate()の一部ではありません)。

どのように3つの箇条書きのすべての世話をする考えですか?私はどうなるのか

+0

IDは既存のエントリでは同じままで、新しいエントリでは自動的にインクリメントする必要がありますか? – tam5

+0

さらに、あなたが作業している 'entry_id'を持つ行だけを変更したいときは、他の行は変更されずに残っています。これが正しいかどうかをお知らせください。 – tam5

+0

@tam私はちょうどそこにあったものを再挿入したくないのです(アイテムが更新されるたびに、システム上でそれを行うより多くの作業があり、すべてをきれいにして再挿入しますか?)2番目のコメントを修正し、私は一度に一つの 'entry_id'に属するキー/値の行だけを扱います。 – Wonka

答えて

1

あなたは、本質的にentry_id == xを持っているテーブル内のすべてのエントリを交換したいので、最も簡単な解決策は、モデル上でこのようなものかもしれません:どんな理由のためにそこには、既存の行に余分なデータを存在していた場合

public function updateEntry(int $entryId, array $newFruits) 
{ 
    // delete old entries 
    self::where('entry_id', $entryId)->delete(); 

    // create new ones 
    foreach ($newFruits as $fruit) { 
     self::save($fruit); 
    } 
} 

置き換えるつもりがない場合は、このメソッドを変更して$newFruitsをチェックして、テーブルに既に値があるかどうかを確認してください。あなたのケースでは、keyvalueの両方をチェックし、すでにデータベースにペアとして存在する場合は削除しません。ただし、これを提供したテーブル構造に基づいている必要はないようで、不必要な複雑さです。

+0

ありがとう@TAM、十分に簡単、私はこれ以上複雑に思う! – Wonka

0

され、新しい果物配列のIDを取得し、IDに基づいて、テーブルの上にwhereNotInを行う(あなたのIDは、両方の機会に同じままと仮定)と例えば結果 を削除し、

$ updateArray = NewFruits-> get() - >リスト( 'id') - > toArray();

$ deleteFruits = Fruit :: whereNotIn( 'id'、$ updateArray) - > get();

foreachの($ deleteFruitとして$ deleteFruits){

$ deleteFruit->は、(削除)。

}

+0

唯一の問題は、idフィールドはテーブル上の自動インクリメント値であるため、私は新しいフルーツIDを持っていないことだと思います。 – Wonka

0

[OK]を、これはあなたがちょうどあなたが維持したいエントリを使用してクエリを実行し、最初のテーブルを切り捨てる必要がある古典的なケースのように思えます。

DB::statement("SET foreign_key_checks = 0"); 

//Model::truncate(); 

Db::table('mytable')->truncate(); 

DB::statement('SET FOREIGN_KEY_CHECKS = 1'); 

次に、改善された新しいリストでコードを再実行します。それが役に立ったら教えてください。

+0

他のキー/値と同じテーブル内に他のエントリもあるので、テーブル全体を切り捨てることはできません。 – Wonka

関連する問題