Issue
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/%24category/edit_token=KKamIVgz6HFOrKa0jZBwxnBdui9bP0KPXB4kD4Uf&_method=PUT&name=name
. What should I do?
body (location of transition to the edit tab):
<x-base-layout>
<div class="space-x-4">
<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 class="py-12">
<div class="mx-auto max-w-7x1 sm:px-6 lg:px-8">
<div class="overflow-hidden shadow-x1 sm:rounded-lg">
<table class="w-full">
<thead class="font-bold bg-dark-200">
<tr>
<th class="px-2 py-3 text-xs tracking-wider text-left uppercase"></th>
<th class="px-2 py-3 text-xs tracking-wider text-left uppercase">
Id
</th>
<th class="px-2 py-3 text-xs tracking-wider text-left uppercase">
Name
</th>
<th class="px-2 py-3 text-xs tracking-wider text-left uppercase">
Sub Categories
</th>
<th class="px-2 py-3 text-xs tracking-wider text-left uppercase">
Created Date
</th>
<th class="px-2 py-3 text-xs tracking-wider text-left uppercase">
Updated Date
</th>
<th class="px-2 py-3 text-xs tracking-wider text-left uppercase">
Actions
</th>
</tr>
</thead>
<tbody class="text-xs bg-dark-300">
@foreach ($categories as $category)
<tr>
<td class="px-2 py-4 whitespace-nowrap text-white-600" style="color: black; font-weight: 500;">
</td>
<td class="px-2 py-4 whitespace-nowrap text-white-600" style="color: black; font-weight: 500;">
{{ $category->id }}
</td>
<td class="px-2 py-4 whitespace-nowrap text-white-600" style="color: black; font-weight: 500;">
{{ $category->name }}
</td>
<td class="px-2 py-4 whitespace-nowrap text-white-600" style="color: black; font-weight: 500;">
<ul class="flex">
@foreach ($category->subCategories as $subCategory)
<li class="px-2">{{ $subCategory->name }}, </li>
@endforeach
</ul>
</td>
<td class="px-2 py-4 whitespace-nowrap text-white-600" style="color: black; font-weight: 500;">
{{ $category->created_at->format('m/d/y')}}
</td>
<td class="px-2 py-4 whitespace-nowrap text-white-600" style="color: black; font-weight: 500;">
{{ $category->updated_at->format('m/d/y') }}
</td>
<td class="px-2 py-4 text-sm text-gray-500 whitespace-nowrap">
{{-- EDIT --}}
<div class="flex justify-start space-x-1">
<a href=" {{ route('categories.edit', $category) }} " class="p-1 border-2 border-white-500 rounded-md">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="w-4 h-4 text-gray-500">
<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" class="p-1 border-2 border-primary rounded-md">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="w-4 h-4 text-red-500">
<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 class="space-x-4">
<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 class="py-12">
<div class="max-w-4x1 mx-auto sm:px-6 lg:px-6">
<div class="overflow-hidden bg-dark-300 shadow-x1 sm:rounded-lg">
<div class="p-4">
<form action="{{ route('categories.edit', '$category') }}" method="GET">
@csrf
@method('PUT')
<div>
<x-jet-label for="name" class="text-white-600" value="{{ __('Name') }}" />
<x-jet-input id="name" class="block mt-1 w-full text-dark bg-dark-200 border-white-200" type="text" name="name" :value="old('name')" required autofocus autocomplete="name" />
<span class="text-xs text-white-300">Maximum 80 character</span>
<x-jet-input-error for="name" class="mt-2" />
</div>
<x-jet-button class="ml-4 mt-12">
{{ __('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';
Solution
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 %24
:
http://***/categories/%24category...
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.
Answered By - Don't Panic
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.