Search code examples
laraveleloquenteloquent-relationship

Product Search using geolocation of shops


I am new to Laravel and I am trying to search for product using nearby shops Here is my code

Shop::selectRaw(" id  ,
                     ( 6371 * acos( cos( radians(?) ) *
                       cos( radians( lat ) )
                       * cos( radians( lng ) - radians(?)
                       ) + sin( radians(?) ) *
                       sin( radians( lat ) ) )
                     ) AS distance", [$latitude, $longitude, $latitude])
            ->having("distance", "<", $radius)
            ->orderBy("distance",'asc')->products()->where('name', 'LIKE', '%' . $keyword . '%')->get();

But I am getting this error message:

"message": "Call to undefined method Illuminate\Database\Eloquent\Builder::products()"

Note: The Relationship between shop and product is working in my other functions


Solution

  • I am really confused, why are you using products() after orderBy and all the other clauses ?

    If you are trying to get products from a shop, you do not have to do products(), you have to use Product::...., but if you want to get shops related to products you have to use whereHas('products', ....), read more about it here.

    Your code should be like this:

    $shops = Shop::selectRaw(
            "id, (6371 * acos(
                cos(radians(?)) * cos(radians(lat)) * cos(radians(lng) - radians(?)) + sin(radians(?)) * sin(radians(lat))
            )) AS distance", 
            [$latitude, $longitude, $latitude])
        ->having("distance", "<", $radius)
        ->orderBy("distance",'asc')
        ->whereHas('products', function ($query) use ($keyword) {
            return $query->where('name', 'LIKE', '%' . $keyword . '%');
        })
        ->with('products')
        ->get();
    

    That code will give you shops, you can then do $shops->products.

    But if you want directly to get the products you have to use the Product model:

    $products = Product::where('name', 'LIKE', '%' . $keyword . '%')
        ->whereHas('shops', function ($query) use ($latitude, $longitude, $latitude, $radius) {
            return $query->selectRaw(
                "id, (6371 * acos(
                    cos(radians(?)) * cos(radians(lat)) * cos(radians(lng) - radians(?)) + sin(radians(?)) * sin(radians(lat))
                )) AS distance", 
                [$latitude, $longitude, $latitude]
            )
            ->having("distance", "<", $radius)
            ->orderBy("distance",'asc');
        })
        ->get();