Save array [ ] of form data in same columns individual row - Laravel

Viewed 33

when the user click add more and submit their form data, I'm having a problem saving form array like this (service[], Amount[], Description[]) in database rows. I have two related tables of invoices and invoice_details, i want the form array to submit the list of form data into the invoice_details table. I have successfully created the models and relations between the invoice and invoice_details.

enter image description here

<!--Blade --> 

<div class="service-box">

                          <div class="row">

                            <div class="col-md-12 service-group">
                                  <div class="row">
                                      <div class="form-group mb-3 col-md-6">
                                          <label class="form-label">Service</label>
                                          <div >
                                              <select type="text" class="form-select" placeholder="Services" value="" name="service[]" id="service">
                                                  <option value="" disabled selected>Select your option</option>
                                                  @foreach ($services as $service)
                                                      <option value="{{$service->service_name}}"  data-id="{{$service->amount}}">{{$service->service_name}}</option>
                                                  @endforeach
                                                  
                                                  
                                              </select>
                                              
                                          </div>
                                          </div>
              
                                          <div class="form-group mb-3 col-md-6">
                                          <label class="form-label">Amount</label>
                                          <div >
                                              <input type="text" class="form-control" name="amount[]" id="amount" placeholder="Amount" readonly>
                                        
                                          </div>
                                      </div>
                                      <div class="form-group mb-3 col-md-12">
                                        <label class="form-label">Description</label>
                                        <textarea class="form-control" id="description" name="description[]" rows="6" placeholder="Description.." ></textarea>
                                    </div>
                                  </div>

                            </div>

                            
                          </div>

                      </div>
        //Controller

        $invoicedetailModel = new Invoice_detail;


        //Here is where the problem lies, I have to save for arrays.
        $invoicedetailModel->service = request('service');
        $invoicedetailModel->amount = request('amount');
        $invoicedetailModel->description = request('description');

        $invoiceModel->Invoice_details()->save($invoicedetailModel);
1 Answers

It seems to me (correct me if I'm misinterpreting) that you're trying to save a batch of different InvoiceDetails and attach them to an original Invoice model.

The problem here is that you're trying to do so by passing arrays to a single invoiceDetails model so let's suppose you have the you have two detail instances passed by form you would have the request parameters structured like this:

$request->service: ['serviceX','serviceY']
$request->amount: [1,2]
$request->description: ['Lorem', 'Ipsum']

So if you tried to create the model you're trying to save in your code you would be doing something like this:

Invoice_Details::create([
    'service' => ['serviceX', 'serviceY'],
    'amount' => [1,2]
    'description' => ['Lorem', 'Ipsum']
]);

Which can not work because those values are not set as Json to the database, and also explains why the createMany is not working, because there's a single object that uses an array of values for each value. What you might want is a situation like this:

Invoice_Details::createMany([
    [
        'service' => 'serviceX',
        'amount' => 1
        'description' => 'Lorem'
    ],
    [
        'service' => 'serviceY',
        'amount' => 2
        'description' => 'Ipsum'
    ]
]);

So you should iterate the request parameters and save a whole array of single models rather than try to stuff everything into a single one.

Also, it's pretty legitimate to ask yourself "Sure, but they all have two parameters, why doesn't it just split them when I use the createMany method?" Well, let's suppose the same situation with different parameters:

$request->service: ['serviceX','serviceY']
$request->amount: [1,2]
$request->description: ['Ipsum']

To which model does that description belong to? We could just go by appearence order, but this kind of assumption might lead to huge problems in case of bad implementations. This sadly means that everytime we need to create multiple models we need to define every single one, even though it means adding an iteration beforehand.

TL;DR: Instead of an array of parameters you need an array of models. Iterate through your parameters and build your models before saving them.

//Supposing you already fetched the arrays and they are all of the same length
$details = [];

foreach($services as $key => $service) {

        $invoicedetailModel = new Invoice_detail();

        $invoicedetailModel->service = $services[$key];
        $invoicedetailModel->amount = $amounts[$key];
        $invoicedetailModel->description = $descriptions[$key]);

        $details[] = $invoicedetailModel;
}
// code to create and attach the many models
Related