I get that we need to match the method to the action when submitting forms, but this has me baffled. I'm trying to store a new category to my database using
<form @submit.prevent="form.post('categories.store')">
I have no mention of 'destroy' or 'delete' anywhere on the page, so I don't understand why laravel thinks I'm trying to delete something.
My routes are:
Route::resource('categories', CategoryController::class)
->only(['create', 'store', 'edit', 'destroy'])
->middleware(['auth', 'verified']);
the vue is:
<script setup>
import InputError from '@/Components/InputError.vue';
import InputLabel from '@/Components/InputLabel.vue';
import PrimaryButton from '@/Components/PrimaryButton.vue';
import TextInput from '@/Components/TextInput.vue';
import Dropdown from '@/Components/Dropdown.vue';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import { Head, Link, useForm } from '@inertiajs/inertia-vue3';
import { Inertia } from '@inertiajs/inertia';
const props = defineProps({
languages: {
type: Object,
default: () => ({}),
},
games: {
type: Object,
default: () => ({}),
}
});
const form = useForm({
name: 'New Category',
game: '',
language: '',
});
</script>
<template>
<Head title="Dashboard" />
<AuthenticatedLayout>
<template #header>
<h2 >
Create Category
</h2>
</template>
<div >
<div >
<section >
<form @submit.prevent="form.post('categories.store')">
<div >
<div >
<div >
<div >
<InputLabel for="name" value="Category Name"></InputLabel>
<TextInput
v-model="form.name"
id="name"
type="text"
required
autofocus
autocomplete="form.name" />
<InputError :message="form.errors.name" />
</div>
<div >
<InputLabel for="name" value="Game"></InputLabel>
<select v-model="form.game" >
<option v-for="game in $page.props.games" :key="game.id"> {{ game.name }}</option>
</select>
<InputError :message="form.errors.game" />
</div>
<div >
<InputLabel for="name" value="Language"></InputLabel>
<select v-model="form.language" >
<option v-for="language in $page.props.languages" :key="language.id"> {{ language.name }}</option>
</select>
<InputError :message="form.errors.language" />
</div>
<PrimaryButton >Create</PrimaryButton>
</div>
</div>
</div>
</form>
</section>
</div>
</div>
</AuthenticatedLayout>
</template>
and my CategoryController is:
<?php
namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\Language;
use App\Models\Game;
use Inertia\Inertia;
use Illuminate\Http\Request;
class CategoryController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
// query categories details
$words = \DB::table('memory_words')
->select('category_id', \DB::raw('COUNT(id) AS words'))
->groupby('category_id');
$sentences = \DB::table('match_sentences')
->select('category_id', \DB::raw('COUNT(id) AS sentences'))
->groupby('category_id');
$categories = auth()->user()->categories()
->join('games', 'categories.game_id', '=', 'games.id')
->join('languages', 'categories.language_id' ,'=', 'languages.id')
->joinSub($words, 'words', function($join) {
$join->on('categories.id', '=', 'words.category_id');
})
->joinSub($sentences, 'sentences', function ($join) {
$join->on('categories.id', '=', 'sentences.category_id');
})
->select('categories.id', 'categories.name', 'categories.user_id', 'games.name as game', 'languages.name as language', 'words.words', 'sentences.sentences')
->get();
return Inertia::render('Manage', [
'categories' => $categories,
]);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return Inertia::render('Category/Create', [
'games' => Game::all(),
'languages' => Language::all()
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
dd($validated);
$validated = $request->validate([
'name' => 'required|string|max:255',
'game' => 'required|integer',
'language' => 'required|integer',
]);
// check game and language exist
if(is_null(Game::find($request->game))) {
return;
}
if(is_null(Language::find($request->language))) {
return;
}
Category::create([
'name' => $request->name,
'game' => $request->game,
'language' => $request->language,
]);
return redirect(route('manage'));
}
/**
* Display the specified resource.
*
* @param \App\Models\Category $category
* @return \Illuminate\Http\Response
*/
public function show(Category $category)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Category $category
* @return \Illuminate\Http\Response
*/
public function edit(Category $category)
{
//
}
/**
* 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)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Category $category
* @return \Illuminate\Http\Response
*/
public function destroy(Category $category)
{
//
}
}
Laravel definitely thinks that I'm requesting a 'destroy' because when I remove that option from the routes, I get a 404 error. Yet a search for 'destroy' only brings up the empty functions in each of my models and the files created by Breeze to delete users or sessions.
What could cause this?
CodePudding user response:
I think you need mention the route if you are using Ziggy route in your Inertia js app
<form @submit.prevent="form.post(route('categories.store'))">