Reputation: 79
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
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