質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Q&A

解決済

1回答

4114閲覧

laravelで複数検索機能を作りたい

ORyohei

総合スコア18

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

0グッド

1クリップ

投稿2020/07/14 15:06

編集2020/07/15 02:57

ユーザーテーブル

idnameprefecture

商品テーブル
|id|product_name|price|expiration|user_id|
|:--|:--:|--:|
||||

ある商品を、1,出品したユーザーが住んでいる都道府県、2,商品の賞味期限、3,商品の価格3つの条件で一覧画面から検索できる機能を作っています。if文で各々requestに値が入っていたら条件に合った値を取得しています。しかし都道府県で検索した時、レコードがnullだった時にエラーが返ってきてしまうのを、もしnullならそのまま次の処理に走らせたいのですが、いまいちうまくいきません。また、if文の中で毎回retuenでviewに値を返さないと表示されないのですが、もっといい方法があれば教えていただきたいです。また、もし2つの条件、3つの条件で同時に検索された時、それに合う値を表示するには、また別に処理を書かないといけないのでしょうか。初歩的なことではありますがアドバイスをいただきたいです。

ProductController.php

laravel

1public function index(Request $request) { 2 // Log::debug(print_r($order, true)); 3 4//検索された値を取得 5 $pref = $request->input('prefecture'); 6 $price_from = $request->input('price_from'); 7 $price_until = $request->input('price_until'); 8 $expiration = $request->input('expiration'); 9 $prefs = config('prefectures'); 10 $users = User::where('prefecture', $pref)->first(); 11 //単一のプロパティはgetではなくfirstとります。 12 13//都道府県での検索 14if (isset($pref) ) { 15 $users = User::where('prefecture', $pref)->first(); 16 $products = $users->products()->paginate(10); 17 18 return view('products.index', [ 19 'products' => $products, 20 'prefs' => $prefs, 21 ]); 22} 23 24 25//賞味期限での検索 26 if (isset($expiration) && $expiration === '切れていない'){ 27 //今日の日づけを取得 28 $today = Carbon::today(); 29 //今日の日づけより後の日付けのproductを取得 30 $products = Product::whereDate('expiration_date','>', $today ) 31 ->paginate(10); 32 return view('products.index', [ 33 'products' => $products, 34 'prefs' => $prefs, 35 ]); 36 }elseif(isset($expiration ) && $expiration === '切れている' ) { 37 $today = Carbon::today(); 38 $products = Product::whereDate('expiration_date','<', $today ) 39 ->paginate(10); 40 return view('products.index', [ 41 'products' => $products, 42 'prefs' => $prefs, 43 //'order' =>$order 44 ]); 45 }else { 46 $products = Product::latest()->paginate(10); 47 } 48 //価格での検索 49 if (isset($price_from) && isset($price_until)) { 50 $products = Product::whereBetween('price', [$price_from,$price_until]) 51 ->paginate(10); 52 }else { 53 $products= Product::latest()->paginate(10); 54 } 55 56 return view('products.index', [ 57 'products' => $products, 58 'prefs' => $prefs, 59 ]); 60 }

index.blade.php

blade

1<section class="l-inner-wrapper__s u-bgcolor__accent" id="Salon"> 2 <div class="l-inner__s "> 3 <div class="c-inner--title"></div> 4 <div class="l-inner--body"> 5 <h2 class="p-concept--title">詳細検索</h2> 6 <div class="p-login"> 7 <form method="GET" action=""class="c-form p-form__login"> 8 <ul class="p-form--list"> 9 <li class="p-form--item"> 10 <input type="number" placeholder="価格" class="c-text" name="price_from" value="{{ old('price_from') }}"> 11 </li> 12 <li class="p-form--item"> 13 円〜 14 </li> 15 <li class="p-form--item"> 16 <input type="number" placeholder="" class="c-text" name="price_until" value="{{ old('price_until')}}"> 17 </li> 18 <li class="p-form--item"> 1920 </li> 21 </ul> 22 <ul class="p-form--list"> 23 <li class=""> 24 <li class=" c-text u-border__none"> 25 <select name="prefecture" id="" class=""> 26 <option value="">コンビニ都道府県</option> 27 @foreach($prefs as $pref ) 28 <option value="{{ $pref }}" 29 @if(old('prefecture') === $pref) selected @endif 30 >{{$pref}}</option> 31 @endforeach 32 </select> 33 </li> 34 </li> 35 <li class=""> 36 <li class=" c-text u-border__none"> 37 <select name="expiration" id=""> 38 <option value="" >賞味期限</option> 39 <option value="切れていない" 40 @if(old('expiration')==='切れていない') selected @endif 41 >切れていない 42 </option> 43 <option value="切れている" 44 @if(old('expiration')==='切れている') selected @endif 45 >切れている 46 </option> 47 </select> 48 </li> 49 </li> 50 </ul> 51 <div class=""> 52 <input type="submit" value="検索する" class="c-btn c-btn--search"> 53 </div> 54 </form> 55 </div> 56 </div> 57 </div> 58 </section>

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

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

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

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

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

hina

2020/07/14 20:31

質問内容とは本質的ではないんですが、ユーザーと商品の間にリレーションがあるよう(おそらくproducts belongs to users, users hasMany products)ですが、提示されているテーブルには外部キーを持つカラムが見当たりません……
ORyohei

2020/07/15 02:59

user_idのカラムをつけ忘れていました。実際には存在します。アドバイスありがとうございます。これから試して見ます。
guest

回答1

0

ベストアンサー

都道府県で検索した時、レコードがnullだった時にエラーが返ってきてしまう

そもそも質問のコードには不可解な点が複数あります。

$users = User::where('prefecture', $pref)->first();

この文は最初のif文内とその前で2回呼ばれているようですが、おそらく後者は意図しているものではないものかと思います。
また、$usersとなっているようにも複数の出品者を取りたいものかと思いますがここで取得されるユーザーは単体またはnullです。「単一のプロパティはgetではなくfirstとります。」とわざわざコメントで書かれているとおりなのですが、ここでほしいのはおそらくは単一ではないでしょう。そして、nullであればこのあとのメソッドチェーンでこけるのは当然です。

しかしまあ、おそらくやりたいことは「条件に一致するユーザーの商品を抽出」でしょうのでこうはしません。では代わりにどうするかというと、リレーションのクエリを使います。whereHasが使えます。

たとえば

$users = User::where('prefecture', $pref)->first(); $products = $users->products()->paginate(10);

をリレーションクエリを用いるように置き換えると

Product::whereHas('user', function($query) use ($pref) { $query->where('prefecture', $pref); });

のように書くことができます。


複数の検索条件を指定した場合にすべての条件を指定したい場合はどうすればいいでしょうか、クエリをつなげていけばいいでしょう。上の変更はそれへの第一歩ともいえます。詳細なコードは省略しますが、イメージだけ。

$query = new Product(); if (条件1) { $query = $query->where(...); } if (条件2) { $query = $query->where(...); } ... $products = $query->paginate(10); return view(...);

投稿2020/07/14 20:56

hina

総合スコア132

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

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

ORyohei

2020/07/15 04:43

無事解決することができました!コードも綺麗になりクエリーの知識も整理することが出来ました。本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問