Laravel красноречив с () поиском местоположения

#laravel #laravel-5 #eloquent #geolocation

#ларавель #laravel-5 #eloquent #геолокация #laravel

Вопрос:

Я пытаюсь вернуть список пользователей типа teacher, у которых есть связанный профиль учителя, их класс и местоположение, которые находятся в пределах 15 миль от почтового индекса.

Кажется, что он возвращает каждого пользователя каждого типа, где значения obj равны нулю, если для этой модели и пользователя нет записи, он правильно добавляет расстояние до местоположения, но не фильтрует по расстоянию, не знаю почему.

Но то, что я хочу, — это только пользователи с профилем учителя (модель учителя) и местоположением в пределах 15 миль.

Функция в моей модели

  public function searchLocationsByDistance($query, $lat, $lng, $max_distance = 15){
    $query->getQuery()->locations = [];
    return $query->select('*')
                 ->selectRaw("( 3959 * acos( cos( radians($lat) ) * cos( radians( lat ) )  * cos( radians( lng ) - radians($lng) )   sin( radians($lat) ) * sin(radians(lat)) ) ) AS distance")
                 ->having('distance', '<=', $max_distance)
                 ->orderBy('distance');

}
  

Функция в моем контроллере

   public function search(Request $request){

$input = $request->all();
//Just google api search this populates fine.
$location =  $this->geolocatePostcode( $input['postal_code'] ); 

$instructors=AppUser::with(['teacher', 'teacher.class','teacher.location' => function ($query) 
use($location) {
    $locations = new Location;
    $locations->searchLocationsByDistance($query,$location->lat,$location->lng);
    }])
    //->where('type', '==', 'instructor')
    ->get();

   // var_dump($instructors);
    return response()->json($instructors->toArray());

}
  

Кто-нибудь может посоветовать, что не так с моими запросами, или направить меня в правильном направлении.

Ответ №1:

Правильно ли заменены ваши переменные в вашем необработанном запросе? Есть несколько способов сделать это;

 ->selectRaw("...query some '$lat' more query...")
  

или

 ->selectRaw("...query some {$lat} more query...")
  

Вы могли бы заменить переменные и другим способом;

 ->selectRaw("...query some :lat more query...", ['lat' => $lat])
  

Комментарии:

1. Он корректно возвращает псевдоним расстояния, поэтому можно было бы предположить, что этот бит, по крайней мере, работает. Просто ничего не фильтруется, все пользователи, даже если у них нет записи преподавателя

Ответ №2:

Написанный вами пользовательский запрос вернет все, потому что в этом запросе нет фильтра. Я думаю, что использование метода Laravel whereHas() поможет вам.

Попробуйте это, но вам нужно будет настроить по мере необходимости, как я предполагаю, многое, но это должно дать вам идею, которая поможет:

 $instructors=AppUser::whereHas(['teacher', function($query) use($location){
     $query->with(['class', 'location' => function($q) use($location){
         $locations = new Location;
         $locations->searchLocationsByDistance($q,$location->lat,$location->lng);
     }])->where('type', '==', 'instructor');
}])
    ->get();
  

Кроме того, изменение местоположения внутри запроса может работать не так, как ожидалось, и кажется сложным. Возможно, вы захотите сначала извлечь отфильтрованный список преподавателей, используя только $query->with(['class', 'location']); для этого внутреннего запроса, а затем использовать метод поиска местоположений в этой коллекции. Протестируйте оба способа, чтобы увидеть, какой наиболее эффективен / работает лучше всего.