Saturday, 28 September 2019

How to sort a collection by its relation in laravel

I have a complicated filter for my hotels and in the end i have a collection that I want to sort the parent relations by its nested relationship so here I have as below :

  public function resultFilter($from_date, $to_date, $bed_count, $city_id, $stars, $type_id, $hits, $price, $accommodation_name, $is_recommended, $start_price, $end_price, $has_discount, $facility_id)
    {
//        $data = QueryBuilder::for(Accommodation::class)
//            ->allowedFilters(['city_id','grade_stars','accommodation_type_id'])
//            ->allowedIncludes('gallery')
//            ->when($bed_count, function ($q, $bed_count) {
//                $q->with([
//                    'accommodationRoomsLimited' => function ($q) use ($bed_count) {
//                        $q->where('bed_count', $bed_count);
//                    }
//                ]);
//            })
//            ->paginate(10);
//        ->get();
//            ->orderBy('hits','DESC')->paginate(10);
        $data = Accommodation::with(['city','accommodationFacilities', 'gallery', 'accommodationRoomsLimited.discount', 'accommodationRoomsLimited', 'accommodationRoomsLimited.roomPricingHistorySearch' => function ($query) use ($from_date, $to_date) {
            $query->whereDate('from_date', '<=', $from_date);
            $query->whereDate('to_date', '>=', $to_date);
        }])->when($bed_count, function ($q, $bed_count) {
                $q->whereHas('accommodationRoomsLimited', function($query) use ($bed_count) {
                    $query->where('bed_count', $bed_count);
                });
        })->when($accommodation_name, function ($query, $accommodation_name) {
            $query->where('name', 'like', $accommodation_name);
        })->when($is_recommended, function ($query,$is_recommended){
            $query->where('is_recommended', $is_recommended);
        })->when($start_price, function ($query, $start_price) {
                $query->with([
                    'accommodationRoomsLimited.roomPricingHistorySearch' => function ($q) use ($start_price) {
                        $q->where('sales_price', '<', $start_price);
                    }
                ]);
            })->when($has_discount, function ($query, $has_discount) {
                $query->with([
                    'accommodationRoomsLimited' => function ($q) use ($has_discount) {
                        $q->has('discount');
                    }
                ]);
            })
            ->whereIn('city_id', $city_id)
            ->whereIn('grade_stars', $stars)
            ->orWhere('accommodation_type_id', $type_id);
        if ($hits) { // or == 'blabla'
            $data = $data->orderBy('hits','DESC');
        } elseif ($price) { // == A-Z or Z-A for order asc,desc
            $f = $data->get();
            foreach ($f as $datas) {
                foreach ($datas->accommodationRoomsLimited as $g) {
                    dd($data);
                    $data = $data->accommodationRoomsLimited()->orderBy($g->roomPricingHistorySearch->sales_price);
                }
            }
        }
        $data = $data->paginate(10);
        return $data;
    }

So if you read code I added the sales_price that I want to sort my $data by it if the $price exists in the request. So in a short term question, I want to sort $data by sales_price in this query above.

NOTE : this filters may get more complicated so any other best practice or better way for that like spatie Query builder or local scopes would be appreciated although i tried both and yet they have their own limitation



from How to sort a collection by its relation in laravel

No comments:

Post a Comment