Elegant way to get 5 counts from the same query in Laravel - laravel

I have a query that gives me 200 results in 5 differents categories.
What I need is getting count of each categories.
What is the best way to do, make 5 counts or get the complete list, and process it ( it seems more heavy if I have to do a foreach)
Tx!

Laravel is awesome !
https://laravel.com/docs/5.1/collections#method-groupby
As I need the full list, I just get it once, and then I can apply groupby to a collection!
$groups = $users->groupBy('categoryId');
And then I just do
#foreach($groups as $group)
{{ sizeof($group) }}
#endforeach

Related

How to split the result of Laravel paginator

I am using the Laravel paginator on my site. I want to split the query result into 4 parts. Because my design has 2 rows of 3 items each and another 2 rows of 2 items each. So I can't use a single foreach loop for showing the items. In my controller, I have the below code.
$properties = Property::whereHas('createdBy', function ($query) {
$query->where('enabled','=',true);
})->orderBy('created_at', 'desc')->paginate(10);
And in my view, I am trying to split the result. I have tried $properties->take(3) and $properties->chunk(3). But is not working.
Below is the content of paginator.
Please help.

Laravel append overall total value on pagination result

I have a Laravel query using pagination.
I want to be able to return the result based on the pagination but also get the overall total of the query and append this to the return. So for example the pagination is set to 5 but the overall total might be 20.
$query = Model::paginate(5);
$queryTotal = $query->total();
$query->append($queryTotal);
return $query;
The Laravel Paginator does this already.
You can see that when serializing results to JSON there is a total key which represents all rows matching that query.
You can also see there is a total method available from the paginator:
$results->total()
Along side other methods that can be found in the Pagination Docs
$query = Model::paginate(5);
return $query;
You can access overall total using
{{ $query->total() }}
For more Info read Paginator instance
The paginate function returns a LengthAwarePaginator object. It simply not possible to add another field to this object.
Your best option is to manually create a new collection in which you merge the LengthAwarePaginator with your newly added data.
An example would be:
$query = Model::paginate(5);
$addition = collect(['totalResult' => $query->total()]);
$queryData = $addition->merge($query);
return $queryData;
Naturally, if you just return the LengthAwarePaginator object, you can simply call the total() function, if you use it in your blade files for example.
Hope this helps!

orderBy-querybuilder and pagination in laravel 5

I'm trying to make an orderBy in my query and a pagination for the items from a gallery, but instead of sort the complete query, laravel order only page-by-page content, so if I order desc it only works 1 page, when I go to the next page I can find values really different (ordered, but without relationship with the first page).
Here is my query:
$product = DB::table("product")
->leftJoin("provider","product.provider_id","=","provider.id")
->orderBy("daily_sales","DESC")
->select('product.*','provider.comercial_name')
->paginate(6);
You can try:
$product = DB::table("product")
->leftJoin("provider","product.provider_id","=","provider.id")
->select('product.*','provider.comercial_name')
->orderBy("daily_sales","DESC")
->paginate(6);

Laravel returns undefined offset 0 when trying to print from array

Controller
$new_products = Product::with('images')->orderBy('created_at', 'desc')->take(10)->get();
return view('site/home', compact('new_products'));
View
{{ $new_product->images[0]->image_name }}
This gives me error undefined offset 0. How do i print the values of images?
values returned on dd($new_products)
If you want to get the first item, you can use the first method.
{{ $new_product->images->first()->image_name }}
You also have the offsetGet method to get an item at a given offset.
{{ $new_product->images->offsetGet(0)->image_name }}
You can also loop through the collection though and do this:
#foreach ($new_product->images as $image)
{{ $image->image_name }}
#endforeach
Note: The first two method will only work if your products have images. If they don't, then Laravel will return an empty collection. The third method of looping through the collection will work in all cases.
If you want to make sure that products have images, you can use the has method.
$new_products = Product::with('images')->has('images')->orderBy('created_at', 'desc')->take(10)->get();
This will only return products that have at least one image.
Docs on collection methods: http://laravel.com/docs/master/collections#method-first
Docs on relationships: http://laravel.com/docs/5.1/eloquent-relationships
From the out it appears that $new_product is also an array of two items,
{{ $new_product[0]->images[0]->image_name }}
Edit: Thomas Kim has a better answer
Your relation (images) is a collection object, if you all() method on that then you'll get the underlying array so then you can access any item from array using the index:
{{ $new_product->images->all()[0]->image_name }}
Also toArray() method will work:
{{ $new_product->images->toArray()[0]['image_name'] }}
So, either pass the array to your view like $new_product->all() or loop it. You may check the documentation here for more information about Collection object in Laravel.

SQL Join/LeftJoin Statement Returning Null

I'm trying to join two queries with this statement:
$item = Category::where('type', $item)
->leftJoin('inventory', 'inventory.id', '=', 'categories.id')
->get();
return View::make('general.buy')
->with('items', $item);
This is my view (this returns NULL):
#foreach ($items as $item)
{{ $item->id }}
#endforeach
The problem is that if there is no inventory id value equal to the category id field, the query returns the id as NULL.
Does anyone know why this is happening and how I can solve it? I should also mention that I am new to laravel, so please keep that in mind when rating this question. Thanks in advance!
I think you answered your own question. It's more about what LEFT JOIN means. You have two tables, inventory and category correct? According to your query (or at least what I can tell) this will generate SQL simliar to
SELECT FROM category LEFT JOIN inventory on inventory.id = categories.id
This says, select ALL rows from category and if they have a match in inventory fill in the columns queried (inventory.id) then supply that value, otherwise return null in that column.
Given this seems to be a somewhat unexpected result to you, I can't help but notice that the naming convention seems slightly off (but I'm not as familiar with laravel). I would assume that instead of merging on categories.id you would merge on category.id (which would seem to match the rest of the schema).
Based on what and how you're querying, the results appear to be correct.

Resources