skip to Main Content

please help, I’ve been stuck here since then.
I want to insert shipmentrequestitem from shipmentrequest model using update method

public function update(UpdateShipmentRequestRequest $request, $id)
{
    $shipmentRequest = ShipmentRequest::with(
        'shipmentRequestItems',
        )->where('id',$id)->first();
    $shipmentRequest->update($request->all());
    $validatedData = $request->validated();
    $shipmentRequestItems = $validatedData['shipmentRequestItems'];
    // $shipmentRequest = ShipmentRequest::find($id);
    
    $existingItems = [];
    foreach ($shipmentRequestItems as $value) {
        DB::beginTransaction();
        if (is_array($value)) {
            $shipmentRequestItem = new ShipmentRequestItem;
            $shipmentRequestItem->name = $value["name"];
            $shipmentRequestItem->quantity = $value["quantity"];
            $shipmentRequestItem->shipment_request_id = $shipmentRequest->id;
    
            // Save the ShipmentRequestItem to the database
            $shipmentRequestItem->save();
            $shipmentRequest->shipmentRequestItems()->create(['name' => $value['name'], 'quantity'=> $value['quantity']]);
            $shipmentRequest->shipmentRequestItems()->save($shipmentRequestItem);
            echo json_encode($shipmentRequest);
            echo json_encode($shipmentRequestItem);
        } else {
            $existingItems[] = $value;
        }
    }
    
    $shipmentRequest->shipmentRequestItems()->whereNotIn('id', $existingItems)->delete();
    $shipmentRequest->refresh();
    return new ShipmentRequestResource($shipmentRequest);
}

When I try to output $shipmentRequest->shipmentRequestItems(), it successfully being added but its not added back to database table. It also increment the id so I wonder what causes it.

Here is my migration
I’m not sure if this is the correct way though

Here is my model
I tried mapping the correct column to specify it

I already tried inserting using different methods but it always have the same result. It’s not adding to database

2

Answers


  1. Chosen as BEST ANSWER

    thanks for cooperating. Apparently, it was caused by $shipmentRequest->refresh(); line in which it doesn't execute any related changes from the current model. I initially put it to remove the deleted ids from UI that I mapped from the request.


  2. The problem here is that you’re starting a transaction, and you’re making changes to your models, but you’re not committing them to your database.

    In order to commit these changes to your database, you need to call the commit() method on the DB facade as follows:

    public function update(UpdateShipmentRequestRequest $request, $id)
    {
        $shipmentRequest = ShipmentRequest::with(
            'shipmentRequestItems',
            )->where('id',$id)->first();
        $shipmentRequest->update($request->all());
        $validatedData = $request->validated();
        $shipmentRequestItems = $validatedData['shipmentRequestItems'];
        // $shipmentRequest = ShipmentRequest::find($id);
        
        $existingItems = [];
        foreach ($shipmentRequestItems as $value) {
            DB::beginTransaction();
            if (is_array($value)) {
                $shipmentRequestItem = new ShipmentRequestItem;
                $shipmentRequestItem->name = $value["name"];
                $shipmentRequestItem->quantity = $value["quantity"];
                $shipmentRequestItem->shipment_request_id = $shipmentRequest->id;
        
                // Save the ShipmentRequestItem to the database
                $shipmentRequestItem->save();
                $shipmentRequest->shipmentRequestItems()->create(['name' => $value['name'], 'quantity'=> $value['quantity']]);
                $shipmentRequest->shipmentRequestItems()->save($shipmentRequestItem);
                echo json_encode($shipmentRequest);
                echo json_encode($shipmentRequestItem);
            } else {
                $existingItems[] = $value;
            }
            DB::commit(); // <-- ADD THIS LINE
        }
        
        $shipmentRequest->shipmentRequestItems()->whereNotIn('id', $existingItems)->delete();
        $shipmentRequest->refresh();
        return new ShipmentRequestResource($shipmentRequest);
    }
    

    However, since you’re doing inserts in multiple related tables at the same time, I recommend you to put all your database manipulation operations inside the transaction, for example:

    public function update(UpdateShipmentRequestRequest $request, $id)
    {
        DB::beginTransaction(); // START THE TRANSACTION
        $shipmentRequest = ShipmentRequest::with(
            'shipmentRequestItems',
            )->where('id',$id)->first();
        $shipmentRequest->update($request->all());
        $validatedData = $request->validated();
        $shipmentRequestItems = $validatedData['shipmentRequestItems'];
        // $shipmentRequest = ShipmentRequest::find($id);
        
        $existingItems = [];
    
        foreach ($shipmentRequestItems as $value) {
            if (is_array($value)) {
                $shipmentRequestItem = new ShipmentRequestItem;
                $shipmentRequestItem->name = $value["name"];
                $shipmentRequestItem->quantity = $value["quantity"];
                $shipmentRequestItem->shipment_request_id = $shipmentRequest->id;
        
                // Save the ShipmentRequestItem to the database
                $shipmentRequestItem->save();
                $shipmentRequest->shipmentRequestItems()->create(['name' => $value['name'], 'quantity'=> $value['quantity']]);
                $shipmentRequest->shipmentRequestItems()->save($shipmentRequestItem);
                echo json_encode($shipmentRequest);
                echo json_encode($shipmentRequestItem);
            } else {
                $existingItems[] = $value;
            }
        }
        
        $shipmentRequest->shipmentRequestItems()->whereNotIn('id', $existingItems)->delete();
        DB::commit(); // END THE TRANSACTION AND COMMIT CHANGES
        $shipmentRequest->refresh();
        return new ShipmentRequestResource($shipmentRequest);
    }
    

    This way, if one manipulation operations fails to save to the database, all changes will rollback, preserving the consistency of the data inside the database.


    Regarding the migration file, the usage of the SET keyword to alter the value of the FOREIGN_KEY_CHECKS variable is almost never necessary to do there, and I’ll go as far as calling it a (bad practice) because the SET FOREIGN_KEY_CHECKS statement is specific to MySQL and MariaDB, so you should be careful because the migration files are meant to build your database starting from code, and they work in a portable way. This means that if you use another DBMS for your project you don’t need to adjust anything in your migration files because Laravel knows how to build the specific DDL statements for the used DBMS, but using the SET FOREIGN_KEY_CHECKS will break the portability of the migration files.

    If you’re in a situation where you want to add a foreign key that reference a non-existent yet table, then it’s better to do it inside a separate migration file.


    Regarding the relation definition inside your ShipmentRequestItem model, you don’t need to pass the second argument as shipment_request_id because according to Laravel convention rules, the name of the relation (e.g. shipmentRequest()) is turned into snake case (e.g. shipment_request) and then the suffix _id is appended to it, resulting in the name of the foreign key column (shipment_request_id)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search