Sorting Data Coming from Resource in laravel - laravel

I want to sort data that is coming from Api resource on the basis of their rating that is coming from the resource. I have been working on the SortByDesc method but it's not giving proper results.
public function reviewlist()
{
$post = Post::all();
$list = RatingResource::collection($post);
return $list->sortByDesc('Rating');
}

Got an answer that you have to use this method for applying sort on resource data.
public function reviewlist()
{
$post = Post::all();
$list = RatingResource::collection($post);
$statisticCollection = collect($list);
$sorted = $statisticCollection->sortByDesc('Rating');
return $sorted->values()->all();
}

Related

Laravel Collection paginate does not exist

I'm trying to implement basic pagination when retrieving notifications, but I get the following error.
Method
Illuminate\Notifications\DatabaseNotificationCollection::paginate does
not exist.
public function index()
{
$messages = collect();
$notifications = auth()->user()->unreadNotifications->paginate(5);
foreach ($notifications as $notification) {
$message = NotificationToMessageFactory::make($notification->type)
->toMessage($notification->data);
$messages->push($message);
}
}
You've to call paginate() on query builder instance not on a collection.
Correct syntax will be :
$notifications = auth()->user()->unreadNotifications()->paginate(5);
You should paginate before looping through the collection, otherwise you will be retrieving all records matching the query, when you only need 5. Like this:
$messages = collect();
$notifications = auth()->user()->unreadNotifications()->paginate(5);
foreach($notifications as $notification) {
$message = NotificationToMessageFactory::make($notification->type)->toMessage($notification->data);
$messages->push($message);
}

Collection doesn't exist while trying to send data to two tables in Laravel 8

I was trying to add categories to products. I want to do it with a couple of tables between items and categories. I made a function in my controller to send it to the database. However, when I want to send it, I get the following error, and I don't know I can fix it.
Method Illuminate\Database\Eloquent\Collection::does not exist
Controller
public function store(ItemsValidatorRequest $request)
{
$items_id = Item::select('items_id')->latest()->get();
$item = Item::find($items_id);
$item->categories()->attach($request->categories);
}
Model
public function categories()
{
return $this->BelongsToMany('App\Models\Category');
}
The $items_id would be an array of ids, so the Item::find($items_id) would return collection of Items that each Item has categories. So try to use each higher order messages:
$items_id = Item::select('items_id')->latest()->get();
$items = Item::find($items_id);
$items->each->categories()->attach($request->categories);
or simply:
$items = Item::latest()->get();
$items->each->categories()->attach($request->categories);
public function store(ItemsValidatorRequest $request)
{
// Here the $items_id will be a collection of ids not a single one
$items_id = Item::select('items_id')->latest()->get();
//Here the $item will be a collection of Item records
//Since you are passing an array/collection of id to the find
$item = Item::find($items_id);
//This will error out as collection of Item records do not have categories relation/method on it
$item->categories()->attach($request->categories);
}
So try this
public function store(ItemsValidatorRequest $request)
{
$items_id = Item::select('items_id')->latest()->first();
$item = Item::findOrFail($items_id);
$item->categories()->attach($request->categories);
}

laravel more than one result from single query

I am trying to get all rows and distinct column from single query. but paginate method is only giving result but not pagination option like total prev next etc..
$offers = Offer::whereHas('users', function ($q) use ($authUser) {
$q->where('user_id', $authUser->parent_id);
$q->where('publisher_id', '=', $authUser->id);
});
and distinct column
$websites = $offers->distinct()->get(['website']);
with pivot columns (just wanted to show my full query)
$offers->orderBy($sortBy, $orderBy)->paginate($perPage)->map(function ($offer) {
if (!empty($offer->users)) {
$manager = $publisher = '';
foreach ($offer->users as $user) {
$manager = $user->pivot->user_id;
$publisher = $user->pivot->publisher_id;
}
$offer->manager = $manager;
$offer->publisher = $publisher;
}
return $offer;
});
Return
return response()->json([
'offers' => $offers,
'websites' => $websites
], 200);
hope my question will make sense.
Thanks.
You should run getCollection() before mapping to get the paginator's underlying collection.
(https://laravel.com/api/7.x/Illuminate/Pagination/LengthAwarePaginator.html#method_getCollection)
$offers->orderBy($sortBy, $orderBy)->paginate($perPage)
->getCollection()
->map(function ($offer) {
// ...
return $offer;
});
I'm answering based on it being $offers:
Your usage of map() is copying the modified results of your paginate() call to a new collection and that collection does not include the pagination information. That's why you no longer have pagination information.
Since there result of paginate() is already a usable collection, you can use each() instead of map() which will alter the objects in-place.

Sorting collections in Laravel

I've got a little problem with my Laravel controller and sorting it:
public function index()
{
$achievements = Achievement::all();
$news = News::all();
$livingspaces = Livingspace::all();
$therapies = Therapy::all();
$events = Event::all();
$collection = collect();
foreach ($achievements as $achievement) {
$collection->push($achievement);
}
foreach ($news as $new) {
$collection->push($new);
}
foreach ($livingspaces as $livingspace) {
$collection->push($livingspace);
}
foreach ($events as $event) {
$collection->push($event);
}
foreach ($therapies as $therapy) {
$collection->push($therapy);
}
$sortedData = $collection->sortBy('category')->sortByDesc('created_at');
return response()->json([
'sortedData' => $sortedData
], 200);
}
It's not sorting at all. It should sort if after the data in the created_at timestamp which comes out of the box when creating a new migration for a Laravel controller. But I can't sort the data. I think it has something to do with pushing the data from the DB directly into the collection and it's not looking for "created_at" at all. It's not giving any errors or anything its just not doing anything. The same goes for sortBy.
sortByDesc method has the same signature as the sortBy method, but will sort the collection in the opposite order. By default sortBy to do the ascending operation. If you want to sort by decending:
$sortedData = $collection->sortBy('category', true);

laravel 5.2 if else to query database

stuck on a form that allows the user to enter a value into a choice of two fields. I can query the database using one field but want to add more range to database queries. With the following code below when i try to access the page to query it just shows me a white screen.
public function index()
{
$data = $request->all();
if(!empty($data['pstoreNum']))
{
$pstoreNum = $data['pstoreNum'];
$result = DB::table('perfumes')->where('StoreNumber','=',$pstoreNum)
->get();
return view('perfumes',compact('result'));
}
else if(!empty($data['pweekNum']))
{
$pweekNum = $data['pweekNum'];
$result = DB::table('perfumes')->where('WeekNumber','=',$pweekNum)
->get();
return view('perfumes',compact('result'));
}
}
My routes file simple calls the index function. Any help would be appreciated.
You can add query functions within your query like so
public function index(Request $request)
{
$data = $request->all();
$result = \DB::table('perfumes')->where(function($query) use ($data) {
if(!empty($data['pstoreNum'])) {
$query->where('StoreNumber', '=', $data['pstoreNum']);
}
if(!empty($data['pweekNum'])) {
$query->where('WeekNumber', '=', $data['pweekNum']);
}
})->get();
return view('perfumes',compact('result'));
}
You can then use the one query and add multiple wheres on various conditions.
https://laravel.com/docs/5.2/queries#advanced-where-clauses

Resources