Laravel save multiple images in database - laravel

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();
}

Related

How To Update hasMany relationship data with multiple row at a time in Laravel?

I want to update SubCategory, which has a relationship with Category as a hasMany relationship. Now I want to update both category and subcategory at a time from one form. I want to update every subcategory which belongs to the category. But I can't do that.
Here is category model:
class Category extends Model
{
use HasFactory;
protected $guarded=[];
public function subcategory(){
return $this->hasMany('App\Models\SubCategory');
}
Here is subcategory model:
class SubCategory extends Model
{
use HasFactory;
protected $guarded=[];
public function category(){
return
$this>belongsTo('App\Models\Category','category_id','id');
}
here is update function in controller:
public function categoryUpdate(Request $request,$id){
if (is_null($this->user) || !$this->user->can('categories-update')) {
abort(403, 'Sorry !! You are Unauthorized !');
}
$request->validate([
'name' => 'required|max:191',
'status' => 'required',
]);
$Category=Category::findOrFail($id);
$Category->name = $request->name;
$Category->slug = Str::slug($request->name);
$Category->status = $request->status;
$Category->updated_by=Auth::user()->id;
$Category->update();
if($request->subcategory_name !=['']){
foreach($request->subcategory_name as $subcat){
if($subcat !=''){
SubCategory::create([
'name'=>json_encode($subcat),
'slug'=>Str::slug(json_encode($subcat)),
'category_id'=>$id,
'created_by' =>Auth::user()->id,
]);
}
}
}
Alert::success('Success','Category has been updated successfully!');
return redirect()->route('category.index');
}
I don't know the code to update multiple subcategories at a time.
Here is the Html form
<form action="{{ route('category.update', $data->id) }}" method="POST">
#csrf
<div class="form-group">
<label for="" class="mb-2">Category name</label>
<input name="name" class="form-control" value="{{ $data->name }}" type="text"
#error('name') is-invalid #enderror" placeholder="Name">
#error('name')
<div class="text-danger">* {{ $message }}</div>
#enderror
</div><br>
<div class="form-group">
<label for="" class="mb-2">SubCategory name</label>
#foreach ($subcat as $sub)
<div class="d-flex w-70 justify-content between mb-2">
<input name="subcategoryname[]" id="subcategoryname" class="form-control w-50" type="text" value="{{json_decode($sub->name)}}"></input>
<button onclick="deleteSubcategory({{$sub->id}})" id="delete_subcat" class="btn btn-danger btn-sm ms-2"><i
class="fa fa-trash text-dark" style="font-size:20px;color:white!important"
aria-hidden="true"></i></button>
</div>
#endforeach
</div><br>
<div class="form-group mt-2">
<label for="" class="mb-2">Add New SubCategory</label>
<div class="subcategory w-50">
<div class="d-flex mb-2">
<input name="subcategory_name[]" class="form-control" id="name" type="text"
placeholder="Name" multiple>
<span id="add" class="btn btn-dark ms-3">+</span>
</div>
</div>
<div class="form-group mt-2">
<label for="" class="mb-2">Status</label>
<br>
<select name="status" class="form-control" style="width:40%"
#error('status') is-invalid #enderror">
<option value="">--Select Status--</option>
<option value="Active" #if ($data->status == 'Active') selected #endif>Active
</option>
<option value="Inactive" #if ($data->status == 'Inactive') selected #endif>Inactive
</option>
</select>
#error('status')
<div class="text-danger">* {{ $message }}</div>
#enderror
</div>
<div class="form-group mt-4 d-flex justify-content-between">
<button type="button" class="btn btn-secondary btn-sm"
data-bs-dismiss="modal">Cancel</button>
<input class="btn btn-primary btn-sm"type="submit" value="Update">
</div>
</form>
The create method takes array of records you want to save. So you can build an array and pass that array to the create method on the SubCategory.
if($request->subcategory_name !=['']){
$subCategories = [];
foreach($request->subcategory_name as $subcat){
if($subcat !=''){
$subCategories[] = [
'name'=>json_encode($subcat),
'slug'=>Str::slug(json_encode($subcat)),
'category_id'=>$id,
'created_by' =>Auth::user()->id,
];
}
}
SubCategory::updateOrCreate(['name', 'slug'], $subCategories);
}

Using Select in an Edit Form Laravel

Im trying to implement a Edit function to update permissions from an Laravel User, (I already installed Spatie), it parcially works, it save the changes but I cant see the permissions of the role on the Select Form. Any help please
<--CONTROLLER-->
public function edit($id)
{
$role = Role::findById($id);
$permissions = Permission::all();
return view('admin_roles_edit', compact('role','permissions', 'permissions1'));
}
public function update(Request $request, $id)
{
$request->validate([
'name'=>'required|max:30',
]);
$role = Role::findById($id);
$role->update($request->all());
$role->permissions()->sync($request->permissions);
return redirect()->route('admin.roles.index')->with('message', 'El rol se ha actualizado correctamente');
}
<--HTML-->
<form action="{{route('admin.roles.update', $role->id)}}" method="post"
class="form">
#csrf
<div class="form-group has-feedback">
<label class="control-label col-lg-3">Nombre<span
class="text-danger">*</span></label>
<input type="text" class="form-control" name="name"
value="{{$role->name}}" required="required">
#error('name')
<label class="validation-error-label" for="basic">{{$message}}</label>
#enderror
</div>
<div class="form-group has-feedback">
<label class="control-label col-lg-3">Permisos<span
class="text-danger">*</span></label>
<div class="multi-select-full">
<select class="multiselect" multiple="multiple" name="roles">
#foreach($permissions as $permission)
<option value="{{$permission->id}} #if($permission->id == $role->permission) selected #endif">{{$permission->name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group pull-right">
<a href="{{route('admin.roles.index')}}" type="button" class="btn btn-default"><i
class="icon-cross2 position-left"></i>Cancelar
</a>
<button type="submit" class="submit-btn btn btn-success"><i
class="icon-add position-left"></i>Editar
</button>
</div>
</form>
<--RESULT-->
in your controller add this line:
public function edit($id)
{
$role = Role::findById($id);
$permissions = Permission::all();
$rolePermissions = $role->permissions()->pluck('name','id')->toArray();
return view('admin_roles_edit', compact('role','permissions', 'rolePermissions'));
}
update your blade:
<option value="{{$permission->id}}" {{in_array($permission->id, array_keys($rolePermissions)) ? 'selected' : '')}}>{{$permission->name}}</option>
Fixed finally
RoleController.php
public function edit($id)
{
$role = Role::findById($id);
$permissions = Permission::all();
return view('admin_roles_edit', compact('role','permissions'));
}
RoleView.blade.php
<select class="multiselect" multiple="multiple" name="roles">
#foreach($permissions as $permission)
<option value="{{$permission->id}}"
#if($role->hasPermissionTo($permission->id))
selected="selected"
#endif/>{{$permission->name}}</option>
#endforeach
</select>
Fixed Result

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 Error during update - Undefined variable: id

I am working on a project using Laravel-5.8
protected $table = 'ratings';
protected $fillable = [
'rating_type',
'rating_value',
'rating_description',
];
public function rules()
{
return [
'rating_type' => 'required|numeric|min:1|max:10|unique:appraisal_ratings,rating_type,company_id'.$this->id,
];
}
The rating has an id column, and that's the primary key. Why I checked it against company_id is that different companies can have the same rating type.
Controller
public function edit($id)
{
$rating = Rating::where('id', $id)->first();
return view('ratings.edit')
->with('rating', $rating)
->with('rating_types', $this->rating_types)
->with('rating_descriptions', $this->rating_descriptions)
->with('rating_values', $this->rating_values);
}
public function update(UpdateRatingRequest $request, $id)
{
$rating = Rating::find($id);
$rating->rating_type = $request->rating_type;
$rating->rating_value = $request->rating_value;
$rating->rating_description = $request->rating_description;
$rating->save();
Session::flash('success', 'Rating is updated successfully');
return redirect()->route('ratings.index');
}
edit.blade
<form action="{{route('ratings.update', ['id'=>$rating->id])}}" method="post" class="form-horizontal" enctype="multipart/form-data">
{{ csrf_field() }}
<input name="_method" type="hidden" value="PUT">
<div class="card-body">
<div class="form-body">
<div class="row">
<div class="col-12 col-sm-4">
<div class="form-group">
<label class="control-label"> Rating:<span style="color:red;">*</span></label>
<select class="form-control select2bs4" data-placeholder="Choose Rating" tabindex="1" name="rating_type" style="width: 100%;">
<option value="">Select Rating</option>
#foreach($rating_types as $k => $rating_type)
<option value="{{$k}}" #if($rating->rating_type == $k) selected #endif>{{$rating_type}}</option>
#endforeach
</select>
</div>
</div>
<div class="col-12 col-sm-4">
<div class="form-group">
<label class="control-label"> Description:<span style="color:red;">*</span></label>
<select class="form-control select2bs4" data-placeholder="Choose Description" tabindex="1" name="rating_description" style="width: 100%;">
<option value="">Select Description</option>
#foreach($rating_descriptions as $k => $rating_description)
<option value="{{$k}}" #if($rating->rating_description == $k) selected #endif>{{$rating_description}}</option>
#endforeach
</select>
</div>
</div>
<div class="col-12 col-sm-4">
<div class="form-group">
<label class="control-label"> Rating Score:<span style="color:red;">*</span></label>
<select class="form-control select2bs4" data-placeholder="Choose Rating Score" tabindex="1" name="rating_value" style="width: 100%;">
<option value="">Select Rating Score</option>
#foreach($rating_values as $k => $rating_value)
<option value="{{$k}}" #if($rating->rating_value == $k) selected #endif>{{$rating_value}}</option>
#endforeach
</select>
</div>
</div>
</div>
</div>
</div>
<!-- /.card-body -->
<div class="card-footer">
<button type="submit" class="btn btn-primary">{{ trans('global.save') }}</button>
<button type="button" onclick="window.location.href='{{route('ratings.index')}}'" class="btn btn-default">Cancel</button>
</div>
</form>
When I clicked on the save button to update, I got this error:
rating_type already exists.
That error should not have occured since I am doing update.
How do I resolve it?
Thank you.
You are checking the unique on update wrong
Unique Rule Usage
unique:table,column,except,idColumn
* 3rd param is for value for column to except and 4th is for column to except
Fix
//App\Http\Requests\UpdateRatingRequest
'rating_type' => 'required|numeric|min:1|max:10|unique:table_name,rating_type,table_primary_key'.$this->id,

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