実現したいこと
-カテゴリ検索(セレクトボックスでの絞り込み)機能が一度しか実行されないため、その問題を改善したい。
前提
Laravel初心者です。Todoアプリを作成していますが、カテゴリ機能がうまく働かないため質問させて頂きました。
カテゴリ検索をセレクトボックスで実装していますが、一度のみ実行され、検索結果のページから再度検索を行うと検索が実行されません。(404NOT FOUND の画面に遷移します)
URLを確認すると、取得しているカテゴリーのidは指定されたカテゴリのidに変わっているように見えるのですが、何故か画面が404の画面になります。
☆他モデル等の前提☆
-Todoモデル (設定する目標)はcategory_idというカラムを持つ
-CategoryモデルはTodoモデルと1対多の関係の紐づいています
-カテゴリーの検索のメソッドはcategory_search(下記ルーティング)
-GET|HEAD todos/category ...... todos.category_search › TodoController@category_search
発生している問題・エラーメッセージ
下記のような流れでエラーが起こります。
一覧画面→検索実行→検索画面へ遷移され結果表示(成功)→再度検索実行→エラー((404NOT FOUND )(失敗)
このとき、URLを見るとカテゴリのidは変わっているように見えます
(例)こんな感じです...
成功時(/todos/category?_token=…&category_id=2)
失敗時(/todos/todos/category?_token=…&category_id=4)
※ちなみに再度一覧画面に戻って検索をかけると検索は成功します
該当のソースコード
Todo.php (モデル)
php
1<?php 2namespace App\Models; 3use Illuminate\Database\Eloquent\Factories\HasFactory; 4use Illuminate\Database\Eloquent\Model; 5 6class Todo extends Model 7{ 8 use HasFactory; 9 10 // リレーション 11 //一つの 大目標(todo)は一人のユーザーと紐づく 12 public function user() 13 { 14 return $this->belongsTo('App\Models\User'); 15 } 16 17 //一つの 大目標(todo)は一つのカテゴリと紐づく 18 public function category() 19 { 20 return $this->belongsTo('App\Models\Category'); 21 } 22 23 // ひとつの大目標(todo)はいくつかの小目標(todolists)を持つことができる 24 public function todo_lists() 25 { 26 return $this->hasMany('App\Models\TodoList'); 27 } 28 // リレーション ここまで 29} 30
Category.php (モデル)
php
1<?php 2namespace App\Models; 3 4use Illuminate\Database\Eloquent\Factories\HasFactory; 5use Illuminate\Database\Eloquent\Model; 6 7class Category extends Model 8{ 9 use HasFactory; 10 11 //categoriesテーブルから::pluckでcategory_nameとidを抽出し、$categoriesに返す関数を作る 12 public function getLists() 13 { 14 $categories = Category::pluck('category_name', 'id'); 15 16 return $categories; 17 } 18 19 // リレーション 20 // 一つのカテゴリーはいくつかの大目標(todo)を持つことができる 21 public function todos() 22 { 23 return $this->hasMany('App\Models\Todos'); 24 } 25 // リレーション ここまで 26 27}
web.php(ルーティング)
php
1<?php 2use App\Http\Controllers\ProfileController; 3use Illuminate\Support\Facades\Route; 4use App\Http\Controllers\TodoController; 5use App\Http\Controllers\TodoListController; 6 7// カテゴリ検索ルーティング 8Route::get('/todos/category',[TodoController::class,'category_search'])->name('todos.category_search'); 9 10Route::resource('todos', TodoController::class); 11// 小目標(todo_list)、大目標(todo)にネスト 12Route::resource('todo.todo_lists',TodoListController::class); 13
Todo.Controller(コントローラ)
php
1<?php 2namespace App\Http\Controllers; 3 4use Illuminate\Http\Request; 5use Carbon\Carbon;//日付取得 6 7use App\Models\Todo;//追加 8use App\Models\User;//追加 9use App\Models\TodoList;//追加 10use App\Models\Category;//追加 11 12class TodoController extends Controller 13{ 14 public function index(Request $request) 15 { 16 // ログインユーザーのタスクのみを表示 17 // 予定日の早い順から表示 18 $todos=Todo::where('user_id',\Auth::user()->id)->get()->sortBy('due_date'); 19 20 //categoriesテーブルからgetLists();関数でcategory_nameとidを取得する 21 $category = new Category; 22 $categories = $category->getLists(); 23 24 // 現在の日時を取得 25 $now = Carbon::now(); 26 return view('todos.index',compact('todos','categories','now'); 27 } 28 29 // カテゴリ検索メソッド 30 public function category_search(Request $request) 31 { 32 $category_id= $request->input('category_id'); 33 //categoriesテーブルからgetLists();関数でcategory_nameとidを取得する 34 $category = new Category; 35 $categories = $category->getLists(); 36 37 $todos=Todo::where('user_id',\Auth::user()->id)->where('category_id',$category_id)->get()->sortBy('due_date'); 38 39 // 現在の日時を取得 40 $now = Carbon::now(); 41 return view('todos.category_search',compact('todos','categories','now','category_id')); 42 } 43 44 public function store(Request $request) 45 { 46 //バリデーション 47 // プラン名、予定日は必須項目 48 // プラン名は30字以内 49 $validated = $request->validate([ 50 'title' => 'required|max:30', 51 'due_date' => 'required', 52 ]); 53 54 // 新規作成 55 $todo = new Todo; 56 57 //データを割り当てる 58 $todo->title = $request->input('title'); 59 $todo->due_date = $request->input('due_date'); 60 $todo->user_id = $request->user()->id; 61 $todo->category_id= $request->input('category_id'); 62 63 // リクエストの確認 64 // dd($request->all()); 65 66 //保存 67 $todo->save(); 68 //リダイレクト 69 return redirect('/todos'); 70 } 71 72} 73
todos/index.blade.php (一覧画面)
todos/category_search.blade.php(カテゴリ画面)
※記述は共通です
(検索で遷移してもレイアウトは共通の画面を表示するため)
php
1<!--content.blade.php--> 2@extends('layouts.app') 3@section('content') 4<div class="container index_box"> 5 <div class="sub_box"> 6 7 <!--新規作成フォーム--> 8 <h2 ><strong>プランを入力しよう!</strong></h2> 9 <form action="/todos" method="post"> 10 @csrf 11 <table> 12 <tr> 13 <td>プラン</td> 14 <td><input type="text" placeholder="プランを入力" name="title" /></td> 15 </tr> 16 <tr> 17 <td>予定日</td> 18 <td><input type="text" name="due_date" id="due_date" value="{{ old('due_date') }}" /></td> 19 </tr> 20 <tr> 21 <td>カテゴリ</td> 22 <td> 23 {{Form::select('category_id',$categories,['id'=>'category_name'])}} 24 </td> 25 </tr> 26 </table> 27 <button type="submit"><strong>作成する</strong></button> 28 </form> 29 <!--新規作成フォームここまで--> 30 31 <!--絞り込み--> 32 <h1>カテゴリ絞り込み</h1> 33 <form action="todos/category" method="get"> 34 @csrf 35 {{Form::select('category_id',$categories,['id'=>'category_name'])}} 36 <button type="submit">検索</button> 37 </form> 38 <!--絞り込みここまで--> 39 </div><!--side_box--> 40 41 <!--タスクの表示ここから--> 42 <div class="main_box"> 43 <h1><strong>マイプランリスト</strong></h1> 44 <!--テーブル--> 45 <table class="table-auto"> 46 <thead> 47 <tr> 48 <th>プラン名</th> 49 <th>予定日</th> 50 <th>カテゴリ</th> 51 </tr> 52 </thead> 53 <!--繰り返し--> 54 @foreach ($todos as $todo) 55 <tbody> 56 <tr> 57 <td> 58 <a href="/todos/{{ $todo->id }}"> 59 {{ $todo->title }} 60 </a> 61 </td> 62 <td>{{ $todo->due_date }}</td> 63 <td>{{$todo->category->category_name}}</td> 64 </tr> 65 </tbody> 66 @endforeach 67 <!--繰り返し--> 68 </table> 69 </div><!--main_box--> 70 <!--タスクの表示ここまで--> 71 </div><!--main--> 72 <footer> 73</footer> 74 75@endsection
試したこと
コントローラを色々書き換えたりしたのですが、うまくいきませんでした。
(曖昧ですみません)
原因分かる方いらっしゃれば教えていただければと思います。
補足情報(FW/ツールのバージョンなど)
Laravel9
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。