J'ai eu deux modules qui sont des modules de produit et d'articles. Ici, la relation entre ces deux modules est: Le produit a de nombreux articles et les articles appartiennent au produit

Le tableau du module produit sont: id, product_name Le tableau du module Items est: id, product_id, item_name, quantité, prix

Ceci est mon code pour UPDATE

public function update(Request $request)
{
    $product = Product::findOrFail($id);
    $product->product_name = $request->product_name;
    $product->update();
    // Remove all items and add new
    $product->items()->delete();
    // Save each items
    if($request->get('item_name')){
        foreach($request->get('item_name') as $key => $item_name)
        {   
            $items = new Items();
            $items->products_id = $product->id;
            $items->item_name = $item_name;
            $items->quantity = $request->quantity[$key];
            $items->price = $request->price[$key];
            $items->save();
        };
    };
}

La structure de ce code UPDATE est à chaque fois qu'il y a une mise à jour, chaque élément sera supprimé et les informations de mise à jour seront ajoutées en tant que nouvelle ligne.

Ce que je veux, c'est que les éléments NE DEVRAIENT PAS être supprimés et ajoutés comme neufs. C'est parce que je souhaite MAINTENIR L'ID DE L'ARTICLE. Que dois-je modifier avec mon code actuel?

0
Ramadhani Baharzah 2 sept. 2020 à 05:43

2 réponses

Meilleure réponse

Si votre objectif est de rendre plus dynamique ajouter , supprimer et mettre à jour les éléments que nous devons gérer autrement! > Malheureusement, Laravel ne fournit pas de méthode telle que sync() pour gérer les relations plusieurs-à-un , uniquement avec plusieurs-à-plusieurs . Vous devez donc insérer une logique supplémentaire dans votre code. Nous utiliserons la clé id pour gérer cette logique.
Donc, pour que cela fonctionne, tous les articles de produit issus de la requête doivent avoir la clé id. Les nouveaux éléments (ceux qui n'existent pas encore dans la base de données) doivent avoir la clé id vide.

Par exemple:

[
  {
    "id": 1,
    "name": "Item 1",
    "quantity": 2,
    "price": 10,
    "product_id": 1,
  },
  {
    "id": "",
    "name": "Item 2",
    "quantity": 3,
    "price": 22,
    "product_id": 1,
  },
  {
    "id": "",
    "name": "Item 3",
    "quantity": 9,
    "price": 33,
    "product_id": 1,
  }
]

Notez que seul le premier élément sera mis à jour, le deuxième et le troisième seront ajoutés car la clé id est vide, et les éléments qui ne sont pas entrés dans le tableau mais qui existent dans la base de données seront supprimés.

Alors allons-y!

1 - Créez 3 variables auxiliaires pour éléments avec identifiant , éléments sans identifiant et identifiant d'élément . Notez que nous utilisons la méthode collect() pour nous aider à gérer les tableaux:

$items_without_id = collect($items)->where('id', '');
$items_with_id = (clone collect($items))->where('id', '!=', '');
$items_ids = $items_with_id->pluck('id');

2 - Mettez à jour les éléments avec l'ID:

foreach ($items_with_id as $item) {
   $obj = App\ProductItem::find($item['id']);
   $obj->name = $item['name'];
   $obj->price = $item['price'];
   $obj->quantity = $item['quantity'];
   $obj->save();
}

3 - Supprimez les éléments qui ne sont pas entrés dans le tableau, nous avons supposé que ces éléments devaient être supprimés:

$product->items()->whereNotIn('id', $items_ids)->delete();

4 - Enfin, insérez les éléments fournis sans identifiant. Nous avons supposé que ces éléments devaient être ajoutés:

$items_without_id->each(function ($item) use ($product) {
   $obj = new App\ProductItem();
   $obj->name = $item['name'];
   $obj->price = $item['price'];
   $obj->quantity = $item['quantity'];
   $obj->product_id = $product->id;
   $obj->save();
});

Code complet:

$product = App\Product::findOrFail($id);
$items = $request->items;

$items_without_id = collect($items)->where('id', '');
$items_with_id = (clone collect($items))->where('id', '!=', '');
$items_ids = $items_with_id->pluck('id');

foreach ($items_with_id as $item) {
   $obj = App\ProductItem::find($item['id']);
   $obj->name = $item['name'];
   $obj->price = $item['price'];
   $obj->quantity = $item['quantity'];
   $obj->save();
}

$product->items()->whereNotIn('id', $items_ids)->delete();

$items_without_id->each(function ($item) use ($product) {
   $obj = new App\ProductItem();
   $obj->name = $item['name'];
   $obj->price = $item['price'];
   $obj->quantity = $item['quantity'];
   $obj->product_id = $product->id;
   $obj->save();
});

Test avec facteur:

entrez la description de l'image ici

J'espère que cela t'aides. Désolé pour mon mauvais anglais.

0
Tarsis Cruz 3 sept. 2020 à 18:30

Essayez la fonction updateOrCreate() pour que le même nom soit mis à jour ou bien cela créera une nouvelle entrée ou vous pouvez ajouter un identifiant unique au 1er tableau et en fonction de ce laravel se mettra à jour

Lien de référence https://laravel.com/docs/7. x / eloquent-relations # the-create-method

public function update(Request $request)
    {
        $product = Product::findOrFail($id);
        $product->product_name = $request->product_name;
        $product->update();
        // Save each items
        if ($request->get('item_name')) {
            foreach ($request->get('item_name') as $key => $item_name) {
                Items::updateOrCreate([
                    "item_name" => $item_name,
                    "products_id" => $product->id,  // add here if u want unique name for each product id 

                ], [
                    
                    "quantity" =>  $request->quantity[$key],
                    "price" => $request->price[$key]
                ]);
            };
        };
    }
0
Kamlesh Paul 2 sept. 2020 à 04:06