I know what the problem is but I couldn't solve it. When I'm creating a category with the code below no problem. But when I try to create a product it doesn't updates the category_id so I get this error every time. The code is same for both controllers (product uses category controller's function)
My ProductController.php
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class ProductController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
$data = Product::all();
return view('admin.product.index', [
'data' => $data
]);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$data = Category::all();
return view('admin.product.create', [
'data' => $data
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$data = new Product();
$data->category_id = $request->category_id;
$data->user_id = 0; // $request->user_id;
$data->title = $request->title;
$data->keywords = $request->keywords;
$data->description = $request->description;
$data->detail = $request->detail;
$data->price = $request->price;
$data->months = $request->months;
$data->status = $request->status;
if ($request -> file('image')){
$data-> image = $request->file('image') -> store('public/images');
}
$data->save();
return redirect('admin/product');
}
/**
* Display the specified resource.
*
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function show(Product $product,$id)
{
//
$data = Product::find($id);
return view('admin.product.show', [
'data' => $data
]);
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function edit(Product $product, $id)
{
//
$data = Product::find($id);
$datalist = Category::all();
return view('admin.product.edit', [
'data' => $data,
'datalist' => $datalist
]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Product $product, $id)
{
//
$data = Product::find($id);
$data->category_id = $request->category_id;
$data->user_id = 0; // $request->user_id;
$data->title = $request->title;
$data->keywords = $request->keywords;
$data->description = $request->description;
$data->detail = $request->detail;
$data->price = $request->price;
$data->months = $request->months;
$data->status = $request->status;
if ($request -> file('image')){
$data-> image = $request->file('image') -> store('public/images');
}
$data->save();
return redirect('admin/product');
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function destroy(Product $product, $id)
{
//
$data = Product::find($id);
if ($data->image){
Storage::delete($data->image);
}
$data->delete();
return redirect('admin/product');
}
}
My CategoryController.php
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Category;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class CategoryController extends Controller
{
protected $appends = [
'getParentsTree'
];
public static function getParentsTree ($category, $title){
if ($category->parent_id == 1)
{
return $title;
}
$parent = Category::find($category->parent_id);
$title = $parent->title.' > '. $title;
return CategoryController::getParentsTree ($parent, $title);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
$data = Category::all();
return view('admin.category.index', [
'data' => $data
]);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$data = Category::all();
return view('admin.category.create', [
'data' => $data
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$data = new Category;
$data->parent_id = $request->parent_id;
$data->title = $request->title;
$data->keywords = $request->keywords;
$data->description = $request->description;
$data->status = $request->status;
if ($request -> file('image')){
$data-> image = $request->file('image') -> store('public/images');
}
$data->save();
return redirect('admin/category');
}
/**
* Display the specified resource.
*
* @param \App\Models\Category $category
* @return \Illuminate\Http\Response
*/
public function show(Category $category,$id)
{
//
$data = Category::find($id);
return view('admin.category.show', [
'data' => $data
]);
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Category $category
* @return \Illuminate\Http\Response
*/
public function edit(Category $category, $id)
{
//
$data = Category::find($id);
$datalist = Category::all();
return view('admin.category.edit', [
'data' => $data,
'datalist' => $datalist
]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Category $category
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Category $category, $id)
{
//
$data = Category::find($id);
$data->parent_id = $request->parent_id;
$data->title = $request->title;
$data->keywords = $request->keywords;
$data->description = $request->description;
$data->status = $request->status;
if ($request -> file('image')){
$data-> image = $request->file('image') -> store('public/images');
}
$data->save();
return redirect('admin/category');
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Category $category
* @return \Illuminate\Http\Response
*/
public function destroy(Category $category, $id)
{
//
$data = Category::find($id);
if ($data->image){
Storage::delete($data->image);
}
$data->delete();
return redirect('admin/category');
}
}
My create.blade.php of product
@extends('layouts.adminbase')
@section('title', 'Add Product')
@section('content')
<!-- Begin Page Content -->
<div >
<!-- Page Heading -->
<h1 >Add Product</h1>
<!-- Collapsable Card-->
<div >
<!-- Card Header - Accordion -->
<a href="#collapseCardExample" data-toggle="collapse"
role="button" aria-expanded="true" aria-controls="collapseCardExample">
<h6 >Product Elements</h6>
</a>
<!-- Card Content - Collapse -->
<div id="collapseCardExample">
<div >
<form action="{{route('admin_product_store')}}" method="POST" enctype="multipart/form-data">
@csrf
<div >
<div >
<label >Parent Product</label>
<select name="parent_id" >
@foreach ($data as $rs)
<option value="{{ $rs->id }}"> {{ \App\Http\Controllers\Admin\CategoryController::getParentsTree($rs, $rs->title) }}</option>
@endforeach
</select>
</div>
<div >
<label for="exampleInputEmail1">Title</label>
<input type="text" name="title" placeholder="Title">
</div>
<div >
<label for="exampleInputEmail1">Keywords</label>
<input type="text" name="keywords" placeholder="Keywords">
</div>
<div >
<label for="exampleInputEmail1">Description</label>
<input type="text" name="description" placeholder="Description">
</div>
<div >
<label for="exampleInputEmail1">Price</label>
<input type="number" name="Price" value="0">
</div>
<div >
<label for="exampleInputEmail1">Months</label>
<input type="number" name="Months" value="0">
</div>
<div >
<label for="exampleInputEmail1">Detail</label>
<textarea name="detail">
</textarea>
</div>
<div >
<label for="exampleInputFile">Image</label>
<div >
<div >
<input type="file" name="image">
<label for="exampleInputFile">Choose image file</label>
</div>
</div>
</div>
<div >
<label>Status</label>
<select name="status">
<option>Enabled</option>
<option>Disabled</option>
</select>
</div>
</div>
<!-- /.card-body -->
<div >
<button type="submit" >Save</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- /.container-fluid -->
</div>
<!-- End of Main Content -->
@endsection
CodePudding user response:
Always use validation in your controllers ,specially in store or update methods . With validation , you can control what kind of data you want to get in your server side and easily change 500 errors(server side) to 400 errors(client side) .
I strongly suggest you to see whole laravel docs about validation in link below :
Beside it , your problem in this specific situation is your send a category id that is not exists in your category table .so when use find function , It returns null .
I suggest you to simply use a validation in your ProductController store method about your category_id , something like :
public function store(Request $request)
{
$validated = $request->validate([
'category_id' => 'required|exists:categories,id',
]);
// Rest of your code
}
And remember to always use validation in your controller . Hope that helps you .