I am creating an application for search ads using Laravel; the application should search for a business by distance (which I already built) and include the latest subscription to the business (if any), so I can order it and then the distance.
Two models are business and subscriptions. A business can have many subscribers (although only one of them will be active).
controller
$businesses = Business::distance($place['lat'], $place['lng'], $request->distance) ->ofShopType($request->shop_type) ->uptoBudget($request->price) ->leftJoin('subscriptions', function($join) { $join->on('businesses.id', '=', 'subscriptions.business_id') ->orderBy('subscriptions.created_at', 'desc'); }); return $businesses = $businesses->get();
Business model
public function scopeDistance($query,$from_latitude,$from_longitude,$distance) { $raw = \DB::raw('ROUND ( ( 3959 * acos( cos( radians('.$from_latitude.') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('.$from_longitude.') ) + sin( radians('.$from_latitude.') ) * sin( radians( latitude ) ) ) ), 1 ) AS distance'); return $query->select('*')->addSelect($raw) ->orderBy( 'distance', 'ASC' ) ->groupBy('businesses.id') ->having('distance', '<=', $distance); }
So the difficulty that I get is that the business.id field is overwritten by subscription.id . I did some searching and read that I turned on ->select('businesses.*') Before leftJoin should fix this, however, after doing this, I get the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'business.distance' in 'having clause' (SQL: select `businesses`.* from `businesses` left join `subscriptions` on `businesses`.`id` = `subscriptions`.`business_id` where `shop_type_id` = 1 and `min_cost` <= 100 group by `distance`, `businesses`.`id` having `distance` <= 50 order by `distance` asc)
The second problem is that the left join seems to be getting the first record, I would like to get the most recent record (on created_at ). You can see that I already have the orderBy line in my controller, but this does not affect, because I see that it still returns the old record, even if a newer record is available.