2017-03-22 3 views
1

私は問題は場所にwhereHasで次の関数Eloquentのための方法はありますか?一致する結果のみを取得することはありますか?私は町/都市が一致する結果を望むのに対し

select * from `services` where exists 
    (select * from `conditions` inner join `condition_service` on `conditions`.`id` = `condition_service`.`condition_id` where `services`.`id` = `condition_service`.`service_id` and `id` in (13, 14) and `conditions`.`deleted_at` is null) 
and exists 
    (select * from `service_locations` inner join `service_location_service` on `service_locations`.`id` = `service_location_service`.`service_location_id` where `services`.`id` = `service_location_service`.`service_id` and 
    (`town` like 'manchester' or `city` like 'manchester' or `town` like 'crewe' or `city` like 'crewe') 
    and `service_locations`.`deleted_at` is null) and `services`.`deleted_at` is null 

を生成

public function index(Request $request) 
    { 
    $results = Service::whereHas('conditions', function ($query) use ($request){ 
     $query->whereIn('id', $request->conditions); 
    }) 
    ->whereHas('locations', function ($query) use ($request){ 

     $ran = false; 
     foreach($request->locations as $location) 
     { 
     if(!$ran) 
     { 
      $query->Where('town', 'like', '%'.$location.'%') 
      ->orWhere('city', 'like', '%'.$location.'%'); 
     } 
     else 
     { 
      $query->orWhere('town', 'like', '%'.$location.'%') 
      ->orWhere('city', 'like', '%'.$location.'%'); 
     } 
     $ran = true; 
     } 
    }) 
    ->with('types', 'contacts', 'locations.datetimes')->toSql(); 

    dd($results); 
    } 

を持っているが、すべての結果を戻します。これを達成するための最良の方法は何ですか?

答えて

1

()でクエリをラップするコールバックを使用して場所クエリをグループ化し、最初の場所を直接処理して配列から削除し、ループを繰り返し処理する必要があると思います。あなたのケースでは以下のコードがうまくいくはずです。

$results = Service::whereHas('conditions', function ($query) use ($request){ 
     $query->whereIn('id', $request->conditions); 
    }) 
    ->whereHas('locations', function ($query) use ($request){ 
     $locations = $request->locations; 
     $query->where(function($builder) use($locations){ 
      $builder->where('town', 'like', '%' . $locations[0] . '%') 
      ->orWhere('city', 'like', '%'.$locations[0].'%'); 
      unset($locations[0]); //remove first item as it is processed 
      foreach($locations as $location) { 
      $builder->orWhere('town', 'like', '%'.$location.'%') 
       ->orWhere('city', 'like', '%'.$location.'%'); 
      } 
     }); 
    }); 

問題がある場合は教えてください。 :)

0

私は最後の夜遅くそれを把握することができました。

私はwith()をクエリの先頭に移動し、場所をコールバックしました。

public static function newGetSearchResults($request) 
    { 
     return Service::with(['types', 'contacts', 'locations.datetimes', 'locations' => function($query) use($request) { 

     $ran = false; 
     foreach($request->locations as $location) 
     { 
      if(!$ran) 
      { 
      $query->Where('town', 'like', '%'.$location.'%') 
      ->orWhere('city', 'like', '%'.$location.'%'); 
      } 
      else 
      { 
      $query->orWhere('town', 'like', '%'.$location.'%') 
      ->orWhere('city', 'like', '%'.$location.'%'); 
      } 
      $ran = true; 
     } 
     }]) 
     ->whereHas('conditions', function ($query) use ($request){ 
     $query->whereIn('id', $request->conditions); 
     })->get(); 
    } 
+0

パラメータグルーピングを使用して、恐ろしい '$ ran'フラグを並べ替えることもできます。https://laravel.com/docs/5.4/queries#parameter-grouping –

関連する問題