Kairaoi Ientumoa
Kairaoi Ientumoa

Reputation: 79

How to save multiple records in a one to many relation laravel 8

I'm trying to save multiple records in a one to many relationship. However I could not with several research and many attempts

Firstly these are my models

Donor Model

    class Donor extends Model
     {
         use HasFactory;

         protected $table ='donors';
         protected $fillable = ['name','description'];

         public function assets()
              {
       
             return $this->hasMany(Asset::class);

         }

         public static $rules = [
             'name' => ['required','string','unique:donors'],
             'description' => ['required','string'],
         ];

     }

Asset Model

    class Asset extends Model
 {
         use HasFactory;

         protected $table ='assets';
         protected $fillable = ['donor_id','name','quantity','unit_price'];

           
         public function donor()
         {
       
             return $this->belongsTo(Donor::class);

         }


         public static $rules = [
             'donor_id' => ['required','integer'],
             'name' => ['required','string'],
             'quantity' => ['required','integer'],
            'unit_price' => ['required'],
         ];

     }

Asset Controller

public function store(Request $request)
    {
         $donor = $request->input('donor_id');
      
        $quantity =  $quantity = $request->input('quantity', []);
        $quantityArray = [];

        foreach($quantity as $qty){
            $quantityArray[] = ['quantity' => $qty];

        }

        $name =  $request->input('name', []);
        $nameArray = [];

        foreach($name as $nm){
            $nameArray[] = ['name' => $nm];

        }

        $unitprice = $request->input('unit_price', []);
        $unitpriceArray = [];

        foreach($unitprice as $up){
            $unitpriceArray[] = ['unit_price' => $up];
          

        }

        $data[] = [...$quantityArray,...$nameArray,...$unitpriceArray];

        // Attempt 1
        Asset::create(['donor_id'=> $donor , $data]
        );
        
          // Attempt 2
        Asset::create(['donor_id'=> $donor] + $data]
       );
        
        // Attempt 3
         Asset::create(['donor_id'=> $donor,
        'unit_price' => $up,
         'name' => $nm,
        'quantity' => $qty]);

        return redirect()->route(static::PREFIX_ROUTE . 'index')
            ->withFlashSuccess(__('was successfully created.'));
    }

In my first Attempt 1 and Attempt 2 the donor id was inserted once in the assets table however the content of $data array does not

In my third Attempt 3 the donor id, unit price, name and quantity were inserted once

I would like to seek assistance on how to save multiple records

Below is an additional dd result of $request->all();

 array:5 [▼
  "_token" => "VlSOGgIS6KzrDpCmTtGJDnYLbNzby38FHAdUV2I5"
  "donor_id" => "1"
  "name" => array:3 [▼
    0 => "speed boat"
    1 => "Laptops"
    2 => "Trailer"
  ]
  "quantity" => array:3 [▼
    0 => "5"
    1 => "3"
    2 => "2"
  ]
  "unit_price" => array:3 [▼
    0 => "4"
    1 => "2"
    2 => "2"
  ]
]

Posted Data

<form action="{{ route("asset.store") }}" method="POST" >
        @csrf
       
       

        <div class="card">
            <div class="card-header">
                Add Asset
            </div>

            <div class="card-body">

            <div class="form-group {{ $errors->has('donor_id') ? 'has-error' : '' }}">
            <label for="donor_id">@lang('Donor')</label>
                                    <select name="donor_id" name="donor_id" class="form-control" required>
                                        @foreach($donors as $donor)
                                            <option value="{{ $donor->id }}" @if($donor->id == old('donor_id', $donor->donor_id))selected="true"@endif> {{ $donor->name }}</option>
                                        @endforeach
                                    </select>
            @if($errors->has('donor_id'))
                <em class="invalid-feedback">
                    {{ $errors->first('donor_id') }}
                </em>
            @endif
           
        </div>

       
            <table class="table" id="assets_table">
                    <thead>
                        <tr>
                            <th>Assets Name</th>
                            <th>Quantity</th>
                            <th>Unit Price</th>
                        </tr>
                    </thead>
                    <tbody>
                     
                        <tr id="asset0">
                               
                                <td>
                                    <input type="text" name="name[]" class="form-control"/>
                                </td>

                                <td>
                                    <input type="number" name="quantity[]" class="form-control"/>
                                </td>

                                <td>
                                    <input type="number" name="unit_price[]" class="form-control"/>
                                </td>
                            </tr>
                       
                            <tr id="asset1"></tr>
                    </tbody>
                </table>

                <div class="row">
                    <div class="col-md-12">
                        <button id="add_row" class=" pull-left">+ Add Row</button>
                        <button id='delete_row' class="pull-right ">- Delete Row</button>
                    </div>
                </div>
            </div>
        </div>
        <div>
            <input class="btn btn-success" type="submit" value="Save">
        </div>
    </form>

Upvotes: 0

Views: 1420

Answers (1)

Yannick Beuchat
Yannick Beuchat

Reputation: 241

You can do save the relationship this way:

$donor = Donor::find($request->input('donor_id'));

// Do the processing of your assets data
// ...


// Save the assets in the donor 
$donor->assets()->saveMany([
    new Asset($assetData1),
    new Asset($assetData2),
]);

Documentation here: https://laravel.com/docs/8.x/eloquent-relationships#inserting-and-updating-related-models

I'm not saying it is the most elegant way, but something like this should work (I'm assuming you have a value in each key of each posted array):

<?php

$donor = Donor::find($request->input('donor_id'));
$assets = [];

$quantity = $quantity = $request->input('quantity', []);
$name = $request->input('name', []);
$unitprice = $request->input('unit_price', []);

// Instantiate each asset object
foreach ($quantity as $key => $qty) {
    $assets[] = new Asset([
        'unit_price' => $unitprice[$key],
        'name' => $name[$key],
        'quantity' => $qty
    ]);
}

// Save the assets in the donor
$donor->assets()->saveMany($assets);

If you can retrieve how many entry are posted, I would rather use a for loop.

Upvotes: 1

Related Questions