#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']);
для этого внутреннего запроса, а затем использовать метод поиска местоположений в этой коллекции. Протестируйте оба способа, чтобы увидеть, какой наиболее эффективен / работает лучше всего.