How to insert multiple data with one form submission [ LARAVEL - Eloquent ] - laravel

I have form where I am planning to insert data into units table .. it has fields course_id | unit_number | unit_title
relationship defined : course has many units .. units belongs to course.
the form is working fine, in case I'm inserting only one unit. but when I insert multiple rows it only stores the last row.
#include('admin.messages')
<form action="{{ route('adminSendCreateUnits')}}" method="post" enctype="multipart/form-data">
{{csrf_field()}}
<div class="row col-12">
<div class="col-sm">
<div class="form-group">
<label style="width:100%; background-color:grey; color:white; padding:15px;" for="course_id">Course</label>
<select name="course_id" class="form-control">
<option>Select Course</option><!--selected by default-->
#foreach ($courses as $course)
<option value="{{$course->id}}">
{{ $course->id}}-{{ $course->crs_title}}
</option>
#endforeach
</select>
</div>
</div>
</div><br>
<label for="unit_number">Unit Number</label>
<select name="unit_number[]" class="form-control">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="10">10</option>
</select>
<label for="unit_title">Unit Title</label>
<input type="text" class="form-control" name="unit_title[]" id="unit_title" placeholder="Unit Title" required>
my unitscontroller.php [ I'm sure this is wrong .. since I was trying stuff and i lack the knowledge]
public function adminSendCreateUnit(Request $request){
$course_id = $request->input('course_id');
$unit_number = $request->input('unit_number', []);
$unit_title = $request->input('unit_title', []);
$newCategoryArray = array(
"course_id"=>$course_id,
"unit_number"=>$unit_number,
'created_at' => \Carbon::now(),
"unit_title"=> $unit_title);
$created = DB::table("units")->insert($newCategoryArray);
if($created){
return redirect()->route("adminAllUnits")->withSuccess('Unit Created successfully!');
}else{
return "Unit was not Created";
}
}
I would like to have the course ID same in all rows .. only Unit number and titles change. would appreciate any input :)

Solved by trying this out.
public function adminSendCreateUnit(Request $request){
$course_id = $request->input('course_id');
$unit_number = $request->input('unit_number', []);
$unit_title = $request->input('unit_title', []);
$units = [];
foreach ($unit_number as $index => $unit) {$units[] = [
"course_id" => $course_id, // change this
"unit_number" => $unit_number[$index],
'created_at' => \Carbon::now(),
"unit_title" => $unit_title[$index]
];
}
$created = Unit::insert($units);
if($created){
return redirect()->route("adminAllUnits")->withSuccess('Unit Created successfully!');
}else{
return "Unit was not Created";
}
}

Related

How to get the old value in a select without unchecked with option formed with an foreach

I need a little help..
In case of validation errors, when the page is reloaded I lose the information entered previously.
This is my code:
Controller:
public function create()
{
$nationalities = array('Italian','Brazilian','Spanish','Romanian');
return view('guest.create', ['nationalities'=>$nationalities);
}
public function store(Request $request)
{
$request->validate([
'nationality' => 'required'
]);
Guest::create([
'nationality' => $request->nationality
]);
return redirect(route('guest.index'));
}
View:
<div class="mb-3">
<label for="nationality" class="form-label fw-bold">Select<span class="required">*</span></label>
<select class="form-select" id="nationality" name="nationality" aria-label="Floating label select example">
#foreach($nationalities as $nationality)
<option value="{{$nationality}}">{{$nationality}}</option>
#endforeach
</select>
</div>
How can I modify the code so that this doesn't happen?
How can you select back what failed if you did not even ask for the old value?
This may or not work depending on how you are validating, but you did not want to show that...
<div class="mb-3">
<label for="nationality" class="form-label fw-bold">Select<span class="required">*</span></label>
<select class="form-select" id="nationality" name="nationality" aria-label="Floating label select example">
#foreach($nationalities as $nationality)
<option value="{{$nationality}}" {{ old('nationality') === $nationality) ? 'selected="selected"' : '' }}>{{$nationality}}</option>
#endforeach
</select>
</div>
<option value="{{$nationality}}" #selected(old('nationality')==$nationality)>
{{$nationality}}
</option>
add the #selected directive in blade.

Laravel validation rules: checking against input array index

In my form the user can add (or remove) licence items which
are generated as input nested arrays:
<div>
<select name="licences[0][type]">
<option value="">- Select -</option>
<option value="car">Car</option>
<option value="motorbike">Motorbike</option>
</select>
<input type="text" name="licences[0][car_spec]" value="">
<input type="text" name="licences[0][motorbike_spec]" value="">
</div>
<div>
<select name="licences[1][type]">
<option value="">- Select -</option>
<option value="car">Car</option>
<option value="motorbike">Motorbike</option>
</select>
<input type="text" name="licences[1][car_spec]" value="">
<input type="text" name="licences[1][motorbike_spec]" value="">
</div>
...
and here are my rules:
$rules = [
'licences.*.type' => 'required',
'licences.*.car_spec' => 'required_if:licences.*.type|car',
'licences.*.motorbike_spec' => 'required_if:licences.*.type|motorbike',
];
Now how can I ensure that the validations match the same index (*) of the licences array ?
For instance, the licences[1][car_spec] input is checked against the licences[1][type] input and not against the licences[0][type].
try like this one:
public function validation(){
$rules = [
'licences.*.type' => 'required',
'licences.*.car_spec' => 'required_if:licences.*.type|car',
'licences.*.motorbike_spec' => 'required_if:licences.*.type|motorbike',
];
foreach($this->request->get('licences') as $key => $value){
$rules['licences.'.$key.'.type'] = 'required';
$rules['licences.'.$key.'.car_spec'] = 'required_if:licences.*.type|car';
$rules['licences.'.$key.'.motorbike_spec'] = 'required_if:licences.*.type|motorbike';
}
return $rules;
}
I hope this works for you.

CRUD Laravel Update in database one to many relationship

I have a CRUD app with cars and for every car I have fields to create a car and images to upload. Everithing is ok, I have one to many relationship and for a car I can have multiple images . When I create a car and I upload photos these photos are stored correctly in database and in my public/images director. The problem is when I want to make the UPDATE par, I don't know how to update the photos in database.
Here is my code, I have update function where I don't know exactly how to make the update .
My cars table:
Schema::create('cars', function (Blueprint $table) {
$table->id();
$table->string('model');
$table->integer('seats');
$table->string('fuel');
$table->integer('year');
$table->string('color');
$table->string('gearbox');
$table->integer('price');
$table->string('coinType');
$table->timestamps();
});
My images table
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->integer('car_id');
$table->string('file_name');
$table->timestamps();
});
My Car model:
class Car extends Model
{
protected $fillable = [
'model',
'seats',
'fuel',
'year',
'color',
'gearbox',
'price',
'coinType',
];
public function images()
{
return $this->hasMany(Image::class);
}
use HasFactory;
}
My Image model:
class Image extends Model
{
protected $fillable = [
'car_id',
'file_name'
];
public function car()
{
return $this->belongsTo(Car::class);
}
use HasFactory;
}
My edit.blade:
#extends('layouts.app')
#section('content')
<div class="row">
<div class="col-sm-8 offset-sm-2">
<h2 class="display-3">Edit a car</h2>
<div>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div><br />
#endif
<form method="post" action="{{ url('cars/'. $res->id) }}" enctype="multipart/form-data">
#csrf
#method('PUT')
<div class="form-group">
<legend>
<label for="model" class="col-form-label">Model :</label>
<input type="text" class="form-control" id="model" name="model" value="{{ $res->model }}">
</legend>
</div>
<div class="form-group ">
<legend>
<label for="seats" class="col-form-label">Seats :</label>
</legend>
<select name="seats" id="seats" value="{{ $res->seats }}">
<option value="2">2</option>
<option value="4" selected="selected">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="fuel" class="col-form-label">Fuel :</label>
</legend>
<select name="fuel" id="fuel" value="{{ $res->fuel }}">
<option value="benzine+gpl">benzine+gpl</option>
<option value="gpl" selected="selected">diesel</option>
<option value="diesel">gpl</option>
<option value="diesel+gpl">diesel+gpl</option>
<option value="benzine">benzine</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="year" class="col-form-label">Year :</label>
</legend>
<input type="text" name="year" id="year" value="{{ $res->year }}">
</div>
<div class="form-group">
<legend>
<label for="color" class="col-form-label">Color :</label>
</legend>
<input type="text" class="form-control" id="color" name="color" value="{{ $res->color }}">
</div>
<div class="form-group ">
<legend>
<label for="gearbox" class="col-form-label">Gearbox :</label>
</legend>
<select name="gearbox" id="gearbox" value="{{ $res->gearbox }}">
<option value="manual">manual</option>
<option value="automatic" selected="selected">automatic</option>
<option value="semiautomatic">semiautomatic</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="price" class="col-form-label">Price :</label>
</legend>
<input type="text" class="form-control" id="price" name="price" value="{{ $res->price }}">
</div>
<div class="form-group ">
<legend>
<label for="coinType" class="col-form-label">CoinType :</label>
</legend>
<select name="coinType" id="coinType" value="{{ $res->coinType }}">
<option value="EUR">EUR</option>
<option value="LEI" selected="selected">LEI</option>
<option value="USD">USD</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="image" class="col-form-label">Upload images :</label>
</legend>
<input type="file" class="form-control" name="images[]" multiple />
</div>
<hr style="height:2px;border-width:0;color:gray;background-color:gray">
<div class="col-xs-12 col-sm-12 col-md-12 ">
<button type="submit" class="btn btn-primary">Add car</button>
<a class="btn btn-primary" href="{{ route('cars.index') }}"> Back</a>
</div>
</div>
</form>
#endsection
My Controller:
public function store(Request $request)
{
$request->validate([
'model' => 'required',
'year' => 'required',
'color' => 'required',
'price'=> 'required',
'file_name.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
$destionationPath = public_path('/images');
$images = [];
$car = new Car();
$car->model = $request->model;
$car->seats = $request->seats;
$car->fuel = $request->fuel;
$car->year = $request->year;
$car->color = $request->color;
$car->gearbox = $request->gearbox;
$car->price = $request->price;
$car->coinType = $request->coinType;
$car->save();
if ($files = $request->file('images')) {
foreach ($files as $file) {
$fileName = $file->getClientOriginalName();
$file->move($destionationPath, $fileName);
$images[] = $fileName;
}
}
foreach ($images as $imag) {
$image = new Image();
$image->car_id = $car->id;
$image->file_name = $imag;
$image->save();
}
return redirect()->route('cars.index')->with('success', 'Car saved !');
}
public function update(Request $request, $id)
{
$request->validate([
'model' => 'required',
'year' => 'required',
'color' => 'required',
'price'=> 'required',
'file_name.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
$destionationPath = public_path('/images');
$images = [];
$car = Car::find($id);
$car->model = $request->model;
$car->seats = $request->seats;
$car->fuel = $request->fuel;
$car->year = $request->year;
$car->color = $request->color;
$car->gearbox = $request->gearbox;
$car->price = $request->price;
$car->coinType = $request->coinType;
$car->update();
if ($files = $request->file('images')) {
foreach ($files as $file) {
$fileName = $file->getClientOriginalName();
$file->move($destionationPath, $fileName);
$images[] = $fileName;
}
}
foreach ($images as $imag) {
//here I don't know what to do
}
return redirect()->route('cars.index')->with('success', 'Car updated !');
}
Thank you.
Looking at your blade file, you don't really show the original images, so the user can't update the images, he can insert new images and the old ones should be deleted, right?
If you want to update the image, you have to show the original images on the blade file with it's ID, so in the backend you can find the image based on the ID
But this should work for you now:
you can just check if the user uploaded any file
if ($files = $request->files('images')) {
...
delete all the old images
$car->images->each(function($image) {
// You probabily should be using Storage facade for this
// this should be the full path, I didn't test it, but if you need add extra methods so it returns the full path to the file
if (file_exists($destionationPath . '/' . $image->file_name) {
unset($destionationPath . '/' . $image->file_name);
}
$image->delete();
});
And then recreate the images like you do on store
foreach ($files as $file) {
$fileName = $file->getClientOriginalName();
$file->move($destionationPath, $fileName);
$images[] = $fileName;
}
foreach ($images as $imag) {
$image = new Image();
$image->car_id = $car->id;
$image->file_name = $imag;
$image->save();
}

Laravel save multiple images in database

I am new in Laravel and I want to make a CRUD with cars and for every car to save multiple images in database.
My blade is :
<form method="post" action="{{ route('cars.store') }}" enctype="multipart/form-data">
#csrf
<div class="form-group">
<legend>
<label for="model" class="col-form-label">Model :</label>
<input type="text" class="form-control" id="model" name="model">
</legend>
</div>
<div class="form-group ">
<legend>
<label for="seats" class="col-form-label">Seats :</label>
</legend>
<select name="seats" id="seats">
<option value="2">2</option>
<option value="4" selected="selected">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="fuel" class="col-form-label">Fuel :</label>
</legend>
<select name="fuel" id="fuel">
<option value="benzine+gpl">benzine+gpl</option>
<option value="gpl" selected="selected">diesel</option>
<option value="diesel">gpl</option>
<option value="diesel+gpl">diesel+gpl</option>
<option value="benzine">benzine</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="year" class="col-form-label">Year :</label>
</legend>
<input type="text" name="year" id="year">
</div>
<div class="form-group">
<legend>
<label for="color" class="col-form-label">Color :</label>
</legend>
<input type="text" class="form-control" id="color" name="color">
</div>
<div class="form-group ">
<legend>
<label for="gearbox" class="col-form-label">Gearbox :</label>
</legend>
<select name="gearbox" id="gearbox">
<option value="manual">manual</option>
<option value="automatic" selected="selected">automatic</option>
<option value="semiautomatic">semiautomatic</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="price" class="col-form-label">Price :</label>
</legend>
<input type="text" class="form-control" id="price" name="price">
</div>
<div class="form-group ">
<legend>
<label for="coinType" class="col-form-label">CoinType :</label>
</legend>
<select name="coinType" id="coinType">
<option value="EUR">EUR</option>
<option value="LEI" selected="selected">LEI</option>
<option value="USD">USD</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="image" class="col-form-label">Upload images :</label>
</legend>
<input type="file" class="form-control" name="images[]" multiple />
</div>
<hr style="height:2px;border-width:0;color:gray;background-color:gray">
<div class="col-xs-12 col-sm-12 col-md-12 ">
<button type="submit" class="btn btn-primary">Add car</button>
<a class="btn btn-primary" href="{{ route('cars.index') }}"> Back</a>
</div>
</div>
</form>
I have the first table named cars like this:
Schema::create('cars', function (Blueprint $table) {
$table->id();
$table->string('model');
$table->integer('seats');
$table->string('fuel');
$table->integer('year');
$table->string('color');
$table->string('gearbox');
$table->integer('price');
$table->string('coinType');
$table->timestamps();
});
and I have the second table with images like this:
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->integer('car_id');
$table->string('file_name');
$table->timestamps();
});
My Controller looks like this:
public function store(Request $request)
{
$request->validate([
'model' => 'required',
'year' => 'required',
'color' => 'required',
'price'=> 'required',
'file_name.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
$destionationPath = public_path('/images');
$images = [];
$car = new Car();
$car->model = $request->model;
$car->seats = $request->seats;
$car->fuel = $request->fuel;
$car->year = $request->year;
$car->color = $request->color;
$car->gearbox = $request->gearbox;
$car->price = $request->price;
$car->coinType = $request->coinType;
$car->save();
$image = new Image();
if ($files = $request->file('images')) {
foreach ($files as $file) {
$fileName = $file->getClientOriginalName();
$file->move($destionationPath, $fileName);
$images[] = $fileName;
}
}
foreach ($images as $imag) {
$image->car_id = $car->id;
$image->file_name = json_encode($imag);
$image->save();
}
}
I have 2 Models: Cars and Image like this:
Car model:
class Car extends Model
{
protected $fillable = [
'model',
'seats',
'fuel',
'year',
'color',
'gearbox',
'price',
'coinType',
];
public function images()
{
$this->hasMany(Image::class);
}
use HasFactory;
}
Image model:
class Image extends Model
{
protected $fillable = [
'car_id',
'file_name'
];
public function car()
{
$this->belongsTo(Car::class);
}
use HasFactory;
}
If I select multiple photos, in my Image table i get just the last image . The othe pictures are overwritten. I put a dump in foreach and I get all the images from the View. But I think that i have a mistake when I save..I don't know how to save correctly.
On every loop, you need to create a new model instance :
foreach ($images as $imag) {
$image = new Image(); // new model instance
$image->car_id = $car->id;
$image->file_name = json_encode($imag);
$image->save();
}

data isn't saving into db using eloquent relation

hi m trying to save data into db using Eloquent ORM one-to-one but it is not saving and not showing any error to fix it (m unable to find any solution about it because it is not showing any error),
public function store(Request $request)
{
$request->validate([
'owner_id' => 'required',
'phone_name' => 'required|unique:phones'
]);
$phone = new Phone;
$phone->owner_id = $request->owner_id;
$phone->phone_name = $request->phone_name;
$phone->save();
return redirect()->route('phone.index')->with('flash_messages_success', 'Phone has been added successfully');
}
protected $fillable = [
'pphone_name', 'owner_id'
];
public function owner()
{
return $this->belongsTo('App\Owner');
}
<form method="POST" action="{{ route('phone.store') }}">
#csrf
<div class="form-group">
<label for="">Phone Title</label>
<input type="text" name="phone_name" class="form-control" id="" placeholder="Phone Name">
</div>
<div class="form-group">
<label>Select Owner</label>
<select class="form-control" name="category_id">
<option selected="">Under Owner</option>
#foreach($owners as $owner)
<option value="{{ $owner->id }}">{{ $owner->owner_name }}</option>
#endforeach
</select>
</div>
<input type="submit" name="submit" class="btn btn-primary" value="submit">
</form>
The issue in select name you named category_id so the view should be:
<select class="form-control" name="owner_id">

Resources