Using Laravel, I'm trying to change data about an object. The "Edit" button works, but when I want to save the changes, it says: "404 NOT FOUND" , the link also looks like:
http://***/categories/$category/edit_token=KKamIVgz6HFOrKa0jZBwxnBdui9bP0KPXB4kD4Uf&_method=PUT&name=name
. What should I do?
body (location of transition to the edit tab):
<x-base-layout>
<div >
<x-jet-nav-link href="/categories">
Index
</x-jet-nav-link>
<x-jet-nav-link href="/categories/create">
Create
</x-jet-nav-link>
</div>
<div >
<div >
<div >
<table >
<thead >
<tr>
<th ></th>
<th >
Id
</th>
<th >
Name
</th>
<th >
Sub Categories
</th>
<th >
Created Date
</th>
<th >
Updated Date
</th>
<th >
Actions
</th>
</tr>
</thead>
<tbody >
@foreach ($categories as $category)
<tr>
<td style="color: black; font-weight: 500;">
</td>
<td style="color: black; font-weight: 500;">
{{ $category->id }}
</td>
<td style="color: black; font-weight: 500;">
{{ $category->name }}
</td>
<td style="color: black; font-weight: 500;">
<ul >
@foreach ($category->subCategories as $subCategory)
<li >{{ $subCategory->name }}, </li>
@endforeach
</ul>
</td>
<td style="color: black; font-weight: 500;">
{{ $category->created_at->format('m/d/y')}}
</td>
<td style="color: black; font-weight: 500;">
{{ $category->updated_at->format('m/d/y') }}
</td>
<td >
{{-- EDIT --}}
<div >
<a href=" {{ route('categories.edit', $category) }} " >
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" >
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
</svg>
</a>
{{-- DELETE --}}
<form action="{{ route('categories.destroy', '$category') }}" method="POST">
@csrf
@method("Delete")
<button type="submit" >
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" >
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
</button>
</form>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</x-base-layout>
CategoryController.php:
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StoreCategoryRequest;
use App\Models\Category;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class CategoryController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$categories = Category::with('subCategories')->whereNull('parent_id')->get();
return view('dashboard.categories.index', compact('categories'));
// return "Hello world!";
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$categories = Category::with('subCategories')->whereNull('parent_id')->get();
return view('dashboard.categories.create', compact('categories'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(StoreCategoryRequest $request)
{
$category = new Category;
$category->name = $request->name;
$category->parent_id = $request->parent_id;
$category->slug = Str::slug($request->name);
$category->save();
return redirect()->route('categories.index')->with('success', 'Category successfully created');
}
/**
* Display the specified resource.
*
* @param \App\Models\Category $category
* @return \Illuminate\Http\Response
*/
public function show(Request $request, Category $category){
return redirect()->route('dashboard.categories.update');
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Category $category
* @return \Illuminate\Http\Response
*/
public function edit(Category $category)
{
$categories = Category::with('subCategories')->whereNull('parent_id')->get();
return view('dashboard.categories.edit', compact('category', 'categories'));
}
/**
* 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)
{
$this->validate($request, [
'name' => ['required', 'unique:categories'],
'parent_id' => ['sometimes', 'nullable']
]);
$category->name = $request->name;
$category->slug = Str::slug($request->name);
$category->save();
return redirect()->route('categories.index')->with('success', 'Category succesfully updated!');
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Category $category
* @return \Illuminate\Http\Response
*/
public function destroy(Category $category)
{
$category->delete();
return redirect()->route('categories.index')->with("success", 'Category succesfully deleted!');
}
}
edit view:
<x-base-layout>
<div >
<x-jet-nav-link href="/categories">
Index
</x-jet-nav-link>
<x-jet-nav-link href="/categories/create">
Create
</x-jet-nav-link>
</div>
<div >
<div >
<div >
<div >
<form action="{{ route('categories.edit', '$category') }}" method="GET">
@csrf
@method('PUT')
<div>
<x-jet-label for="name" value="{{ __('Name') }}" />
<x-jet-input id="name" type="text" name="name" :value="old('name')" required autofocus autocomplete="name" />
<span >Maximum 80 character</span>
<x-jet-input-error for="name" />
</div>
<x-jet-button >
{{ __('Update') }}
</x-jet-button>
</form>
</div>
</div>
</div>
</div>
</x-base-layout>
Route.php:
<?php
use App\Http\Controllers\CategoryController;
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\HomeController;
use Illuminate\Support\Facades\Route;
Route::get('/', [HomeController::class, 'index'])->name('home');
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
Route::resource('categories', CategoryController::class)->middleware("auth");
require __DIR__ . '/auth.php';
CodePudding user response:
There are several problems. First up, the edit form uses:
<form action="{{ route('categories.edit', '$category') }}" method="GET">
@csrf
@method('PUT')
But as with any route which changes data, it should be POST:
<form action="{{ route('categories.edit', '$category') }}" method="POST">
Next, the URL you land on includes $:
http://***/categories/$category...
That's a URL-encoded $. That's because PHP does not interpolate variables in single quotes - '$category' winds up in your URL exactly like that: http://***/categories/$category/.... You need to use double quotes around variables if you want the variable to be interpolated: "$category".
However! You don't actually want any quotes there, as what you have is not the documented way to pass a parameter to a named route. You should use:
<form action="{{ route('categories.edit', ['category' => $category]) }}" method="POST">
Also, an unrelated problem, on the page you've described as the body, you have stray whitespace in your edit links:
<a href=" {{ route('categories.edit', $category) }} "
// ^.........................................^ --- remove those spaces
I'm surprised those links work, those spaces should be removed.
