ichihhd
@ichihhd

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Laravelでソート機能を実装したい。

解決したいこと

商品管理ツールを作成しているのですが、商品一覧画面でテーブルヘッターを押下すると、対応したカラムにてソートを行えるように実装したい。

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

laravelのソート機能のパッケージを使用したのですが、
エラーなどは特にでず、ソート機能が発動しない。

該当するソースコード

product.blade.php

<div class="search">
  <form action="{{ route('product') }}" method="GET">
  @csrf
  <!-- 検索フォーム -->
  <div class="product_name.search">
  <label for="product_name">{{ __('商品名') }}</label>
    <input type="text" name="keyword" id="keyword" >
  </div>  

  <div class="company_name.serch">
  <label for="company_name">{{ __('メーカー') }}<span class="badge badge-danger ml-2">{{ __('必須') }}</span></label>
        <select class="form-control" name="search" id="search">
          <option>{{"メーカーを選択してください"}}</option>
          <option>{{""}}</option>
        @foreach ($companies as $company)
         <option>{{ $company->company_name }}</option>
         @endforeach
        </select>
  </div>

  <div class="price.search">
    <label for="price">{{ __('価格') }}</label>

    <div class="jougen">
    <p>{{ __('上限') }}</p>
    <input type="number" name="jougenprice" id="jougenprice" >
    </div>

    <div class="kagen">
    <p>{{ __('下限') }}</p>
    <input type="number" name="kagenprice" id="kagenprice" >
    </div>

  </div>

  <div class="stock.serach">
  <label for="stock">{{ __('在庫数') }}</label>

    <div class="jougen">
    <p>{{ __('上限') }}</p>
    <input type="number" name="jougenstock" id="jougenstock" >
    </div>

    <div class="kagen">
    <p>{{ __('下限') }}</p>
    <input type="number" name="kagenstock" id="kagenstock" >
    </div>

  </div>
  
  <input type="submit" value="検索" id="kensaku">
  </form>
</div>

<h1>商品一覧</h1>

//ソート機能の実装場所
<table class="table table-striped">
  <thead>
    <tr>
      <th>@sortablelink('id', 'ID')</th>  
      <th>@sortablelink('product_name', '商品名')</th>
      <th>@sortablelink('company_name', 'メーカー')</th>
      <th>@sortablelink('price', '価格')</th>
      <th>@sortablelink('stock', '在庫数')</th>
      <th>@sortablelink('comment', 'コメント')</th>
  </tr>
  </thead>
  <tbody>
    @foreach ($products as $product)
    <tr>
      <td>{{ $product->id }}</td>
      <td>{{ $product->product_name }}</td>
      <td>{{ $product->company_name }}</td>
      <td>{{ $product->price }}</td>
      <td>{{ $product->stock }}</td>
      <td>{{ $product->comment }}</td>
   <td><a href="{{ route('product.detail', ['id'=>$product->id]) }}" class="btn btn-primary">詳細</a></td>
      <td>
        <form action="{{ route('product.destroy', ['id'=>$product->id]) }}" method="POST">
          @csrf
          <button type="submit" class="btn btn-danger" onclick='return confirm("削除しますか?")'>削除</button>
        </form>
      </td>
    </tr>
    @endforeach

Productcontroller.php

public function showList(Request $request)
    {
        // 商品一覧画面表示/検索処理

        $keyword = $request->input('keyword');
        $search = $request->input('search');
        $jougenprice = $request->input('jougenprice');
        $kagenprice = $request->input('kagenprice');
        $jougenstock = $request->input('jougenstock');
        $kagenstock = $request->input('kagenstock');
        

       
        $nonon = new Product();

        // メーカーの検索部分の値挿入
        $model = new Company();
        $companies = $model ->getCompanyNameById();


        // ソート機能と検索機能
        $a = $nonon->search($keyword,$search,$jougenprice,$kagenprice,$jougenstock,$kagenstock);
        $products = $a->sort();

   
       
            
        return view('product', compact('products','keyword','companies','search','jougenprice','kagenprice','jougenstock','kagenstock'));
           
        
    }

Product.php

 public function sort()
    {
        $products = Product::sortable()->get();

        return $products;
    }

public function search($keyword,$search,$jougenprice,$kagenprice,$jougenstock,$kagenstock)
    {
        // 検索処理
        $products = DB::query();

        $products= DB::table('products')
        ->join('companies','company_id','=','companies.id')
        ->select('products.*','companies.company_name','products.price','products.stock');

        if($keyword){
            $products->where('product_name', 'LIKE', "%$keyword%");
        }

        if($search){
            $products->where('company_name', 'LIKE', "%$search%");
        }

        if($jougenprice){
            $products->where('price','<',$jougenprice);
        }

        if($kagenprice){
            $products->where('price','>',$kagenprice);
        }

        if($jougenstock){
            $products->where('stock','<',$jougenstock);
        }

        if($kagenstock){
            $products->where('stock','>',$kagenstock);
        }

        $product= $products->get();

        return $product;
      
    }

    public function sort()
    {
        $products = Product::sortable()->get();

        return $products;
    }
0

1Answer

この部分でソートされるだろうとお考えだと思いますが

// ソート機能と検索機能
$a = $nonon->search($keyword,$search,$jougenprice,$kagenprice,$jougenstock,$kagenstock);
$products = $a->sort();

$a に入っているのは Product クラスではなく
\Illuminate\Database\Eloquent\Collection クラスになります。

なので Product クラスに書かれている sort() ファンクションではなく、Collection クラスの sort() が呼び出されています。

修正箇所

showList()

$products = $nonon->search($keyword,$search,$jougenprice,$kagenprice,$jougenstock,$kagenstock);
// 削除
// $products = $a->sort();

search()

// $product= $products->get();
$product = $products->sortable()->get();

で動きませんかね?
sortable() 使ったことないのではっきりしませんが

0Like

Comments

  1. @ichihhd

    Questioner

    ご回答ありがとうございました。

    ご指摘いただいた通りに改修したところ
    Call to undefined method Illuminate\Database\Query\Builder::sortable()
    というエラーが出ました。

  2. 静的にしか呼び出せないメソッドなんですかね

    search()

       $products= Product::sortable()
            ->join('companies','company_id','=','companies.id')
            ->select('products.*','companies.company_name','products.price','products.stock');
    

    はいかがでしょう

  3. @ichihhd

    Questioner

    コメントありがとうございます。

    できました!
    本当にありがとうございます。

Your answer might help someone💌