sena9718
@sena9718

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

検索フォームを追加したいです。

解決したいこと

Laravelで商品管理システムをつくっています。
検索フォームの作成をしており、色々なサイトを見ながら進めているのですが、
なかなか上手くいきません。
解決法を教えてください。

下の写真のような感じにしたいです。

スクリーンショット 2023-11-10 14.02.36.png

発生している問題・エラー

検索を押しても、404のエラーメッセージが出ます。
また、キーワード検索しても全く関係のないものまで出てくることもありました。

該当するソースコード

index.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <h1 class="mb-4">商品一覧画面</h1>

    <div class="search mt-5">
        <form action="{{ route('products.index') }}" method="GET">
            <input type="search" placeholder="検索キーワード" name="search" value="@if (isset($search)) {{ $search }} @endif">
            <input type="search" placeholder="メーカー名" name="company_id" value="@if (isset($company_id)) {{ $company_id }} @endif">
            <div>
                <button type="submit">検索</button>
            </div>
        </form>

        @foreach($products as $product)
        <a href="{{ route('products.show', )}}"
    </div>

        <div class="products mt-5">
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>商品画像</th>
                    <th>商品名</th>
                    <th>価格</th>
                    <th>在庫数</th>
                    <th>メーカー名</th>
                    <th><a href="{{ route('products.create') }}" class="btn btn-warning">新規登録</a></th>           
                </tr>
            </thead>
            <tbody>
            @foreach ($products as $product)
                <tr>
                    <td>{{ $product->id }}</td>
                    <td><img src="{{ asset($product->img_path) }}" alt="商品画像" width="100"></td>
                    <td>{{ $product->product_name }}</td>
                    <td>{{ $product->price }}</td>
                    <td>{{ $product->stock }}</td>
                    <td>{{ $product->company->company_name }}</td>
                    </td>
                    <td>
                        <a href="{{ route('products.show', $product) }}" class="btn btn-info btn-sm mx-1">詳細</a>
                        <form method="POST" action="{{ route('products.destroy', $product) }}" class="d-inline">
                            @csrf
                            @method('DELETE')
                            <button type="submit" class="btn btn-danger btn-sm mx-1">削除</button>
                        </form>
                    </td>
                </tr>
            @endforeach
            </tbody>
        </table>
        </div>
    </form>

{{ $products->appends(request()->query())->links() }}

</div>
@endsection
ProductController.php
<?php

namespace App\Http\Controllers;

use App\Models\Product;
use App\Models\Company;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ProductController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $query = Product::query();

        if($search = $request->search) {
            $query->where('product_name', 'LIKE', "%{$search}%");
        }
        if($company_id = $request->company_id) {
            $query->where('company_id', 'LIKE', "%{$company_id}%");
        }

        $products = $query->paginate(10);
        return view('products.index', compact('products'));
    }
0

2Answer

検索を押しても、404のエラーメッセージが出ます。

まず次のことを確認してください。

  • formタグのaction属性にどのような値(URL)が入っているか
  • 404になったときのリクエスト(URL、メソッド)
    • アドレスバーのURL
    • デベロッパーツールのネットワーク
    • LaravelやWebサーバーのログ
  • route設定(上記にマッチする設定が存在するか)

また、viewテンプレートが不完全に見えます。(aタグが途中で途切れている。@foreach に対応する@endforeachが無い)
不完全なHTMLで意図しない動作をしている可能性もあります。

                <button type="submit">検索</button>
            </div>
        </form>

        @foreach($products as $product)
        <a href="{{ route('products.show', )}}"
    </div>
1Like

Comments

  1. @sena9718

    Questioner

    コメントありがとうございます。
    ・formタグのaction属性はControllerのindexメソッドへデータが送信されるように書きました。
    ・404になった時のリクエスト
    ⚪︎アドレスバーのリクエスト
        http://127.0.0.1:8000/products/index?company_id=&search=
    ・routeは設定済みです。

    申し訳ございません。
    viewテンプレートを追加で書こうと思っていて、
    誤って途中のまま質問に投稿してしまいました。
    今はひとまず消しました。

    下記記事の内容がつくりたいものと酷似していたので、
    基本的にはこの記事を基に作成を行っております。

  2. 確認ありがとうございます。

    現状をまとめると、
    商品一覧画面(http://127.0.0.1:8000/products/index)の検索フォームで検索を押すと、404ページ(http://127.0.0.1:8000/products/index?company_id=&search=)になる
    という理解でいいでしょうか?

  3. @sena9718

    Questioner

    返信遅くなり申し訳ございません。
    その認識で間違いございません。

  4. では、route設定について確認する必要がありそうです。
    routes/web.phpの内容と、ルートの一覧を記載していただけますか?
    ルートの一覧はコマンドphp artisan route:listで表示できます。

  5. @sena9718

    Questioner

    承知しました。
    下記がroutes/web.phpの内容とルート一覧になります。

    スクリーンショット 2023-11-13 13.52.18.png

    スクリーンショット 2023-11-13 13.52.59.png

    よろしくお願いいたします。

  6. ルート名 products.index が重複しているのが原因だと思われます。
    ルートの一覧を見ると、次のルートにはルート名 products.index が割り当てられています。

    • GET|HEAD /products
    • GET|HEAD /products/index

    ルート名は重複しないように設定する必要があるので、これによって想定外の動作になっているのだと思います。

    Warning!! ルート名は常に一意である必要があります。

    Route::resourcesは複数のルートが追加され、その中には ***.index も含まれます。

    解決策は新しく追加したルートの目的にもよりますが、ルート名が重複しないように変更が必要になります。

  7. @sena9718

    Questioner

    コメントありがとうございます。
    お答えいただいた通りに重複箇所を修正すると、検索機能が正常に働きました。
    とても助けになりました。
    ありがとうございます。

  8. 解決できたようで良かったです。
    解決した質問はクローズしていただけると助かります。

僕の読解力の問題かもしれませんが、

キーワード検索しても

というのは検索ボタンではなく、スクリプトから実行した、ということでしょうか?それとも検索に404なしで成功する場合もある、ということでしょうか?

どちらにせよ、route()の設定が足りているのかもう一度確認してみてください。
https://prograshi.com/framework/laravel/assign-link-by-route-name/
「ルーティングとルート名の設定」以降を参照

それと、検索がおかしいのはおそらく

        if($search = $request->search) {
            $query->where('product_name', 'LIKE', "%{$search}%");
        }
        if($company_id = $request->company_id) {
            $query->where('company_id', 'LIKE', "%{$company_id}%");
        }

この部分で、$request->searchあるいは$request->company_idが空文字列""だと、LIKE検索時に空文字列の前方一致や後方一致がなされるわけですが、この場合全てのデータが該当してしまいます。
空文字列のときを場合分けするべきであると感じます。

0Like

Comments

  1. 失礼しました

    if($company_id = $request->company_id)
    

    で空文字列の場合は検索が実行されませんね。
    どのような形で予想外の結果が得られているのでしょうか?
    データベースと検索結果をご提示いただければ何かわかるかもしれません。

  2. @sena9718

    Questioner

    コメントいただきありがとうございます。
    現状、検索をかけると404|NOT FOUNDの表示が出てきます。

    下記の記事内にあるものとつくりたいものが酷似していたので、
    この記事を基に作成してみたのですが、検索のところがなかなか上手くいかずでして...。

    またこの記事ではDB操作を用いたものがあまりなかったので、そのあたりも現在修正を行なっているところです。

  3. なるほどなるほど、、!
    僕が指していたのは、そちらの記事の「ルーティングを作成する」の項ですが、そちらも実装済みですか?

    それと、検索がうまくいかない理由を一緒に探したいので、うまくいかない場合の元データと検索結果を例示頂ければと思います。

  4. @sena9718

    Questioner

    ルーティングに関しては、実装済みです。

    データは記事にもあるようにSeederとFactoryを使って、ダミーデータを作成しています。

Your answer might help someone💌