🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら

Q&A

解決済

1回答

488閲覧

Laravel カテゴリ検索を実装したが一度しか実行されない

hanasaki

総合スコア3

0グッド

0クリップ

投稿2023/03/11 11:33

実現したいこと

-カテゴリ検索(セレクトボックスでの絞り込み)機能が一度しか実行されないため、その問題を改善したい。

前提

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

ビューのカテゴリを絞り込む際のアクションの記述にミスがありました。
以下のように書き換えたところ正常に動作しました。

-誤<form action="todos/category" method="get">
-正<form action="/todos/category" method="get">

投稿2023/03/12 02:19

hanasaki

総合スコア3

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問