How can I hide empty categories when I query to display them? Empty categories are those that no products are assigned to them..
Here is my controller
public function showSubCats($categoryId) {
$subcats = SubCategories::where('category_id', '=', $categoryId)->get();
return View::make('site.subcategory', [
'subcats' => $subcats
]);
}
Here is the view
#if(count($subcats) > 0)
<div class="row">
#foreach($subcats as $i => $subcategory)
// display categories
#endforeach
#else
There is no products assigned to this category
</div>
#endif
This is my SubCategories model
public function products()
{
return $this->hasMany('Product', 'category_id');
}
public function subcategories()
{
return $this->hasMany('SubCategories', 'category_id');
}
public function lowestProduct() {
return $this->products()->selectRaw('*, max(price) as aggregate')
->groupBy('products.product_id')->orderBy('aggregate');
}
In product table I have column which is sub_cat_id and holds category in which is assigned. If is 0 is not assigned to any category.
How can I hide empty categories now?
You should use where in addition to your model
return $this->hasMany('Action')->where('sub_cat_id', 1);
Note :
I believe that you neeed to take the records only that has sub_cat_id as 1. If not change it to 0 or accordingly.
Hope this helps you
Related
I have looked through the forum, but the solutions I have seen so far, aren't aligning with the issues I'm getting, so, I was hoping someone more informed would help out.
So I have a Category modem and A post model and there relationship is as follows;
on post model:
public function postcategory(){
return $this->belongsTo(PostCategory::class);
}
on category model:
public function posts(){
return $this->hasMany(Post::class)->where('approved', 'true');
}
and I am using slugs to retrieve all the posts that belongs to a certain category slug, using this function:
public function cats($category){
$posts = PostCategory::where('category_slug', $category)->first()->posts;
$category = PostCategory::where('category_slug', $category)->first();
return view('posts', compact('posts', 'category'));
}
Now, I am trying to get the name of the category with the category id stored in the posts table. for example, if I have a category id of 1 and on the category table, if the id number 1 is PHP, how do I return the name PHP instead of the id 1?
Secondly, if I wanted to paginate the view where posts is being compacted to, how do I do that? I switched the code in the controller to this:
$posts = PostCategory::with('posts')->where('category_slug', $category)->paginate(15);
when I dd that line of code, it returns some values (with relations), but when I pass that to the view, I get errors.
Hopefully, someone see this and help me out. :D
on Category Model :
public function posts()
{
return $this->hasMany(Post::class);
}
On Controller :
public function cats($slug)
{
$category = PostCategory::whereSlug($slug)->firstorFail();
$posts= $category->posts()->where('approved', 'true')->paginate(15);
return view('category.show', compact('posts', 'category'));
}
On View :
#foreach($posts as $post)
$post->title
....
#endforeach
{{ $posts->links() }}
I have few products in 3 category (for example), and each product has a brand. I want to show brands which related to products in a specific category.
Models:
--product
--brand
--category
relations:
category has many products
brand has many products
How can I do that?
Considering you have 3 models with relationships like :
Brand Model :
public function products()
{
return $this->hasMany(Product::class);
}
Product Model :
public function brand()
{
return $this->belongsTo(Brand::class);
}
public function category()
{
return $this->belongsTo(Category::class);
}
Category Model :
public function products()
{
return $this->hasMany(Product::class);
}
You can use whereHas :
$brands = Brand::whereHas('products.category', function ($q){
return $q->where('name', 'category_name');
})->get();
Above will give you all brands which has product belonging to category with name as category_name.
If you want to get product and category details then you can eager load :
$brands = Brand::whereHas('products.category', function ($q){
return $q->where('name', 'category_name');
})->with(['products', 'products.category'])->get();
I have parent and child categories on the page. What I'm trying to do is when there is no products and no sub-categories assigned in some parent category to not be shown on the page.
So I have this in Category model
public function item()
{
return $this->hasMany('Item','category_id');
}
public function children()
{
return $this->hasMany('App\Category', 'parent_id');
}
public function getCategories()
{
$categoires = Category::where('parent_id',0)->get();
$categoires = $this->addRelation($categoires);
return $categoires;
}
public function selectChild( $id )
{
$categoires = Category::where('parent_id',$id)->where('published', 1)->get();
$categoires = $this->addRelation($categoires);
return $categoires;
}
This in the controller
public function index()
{
$Category = new Category;
$allCategories = $Category->getCategories();
return view('frontend.home', compact('allCategories', 'unviewedMessagesCount'));
}
And this on the blade view
#foreach($allCategories as $category)
{!!$category->title!!} ({!! $category->itemCount!!})
<p class="card-text">
#foreach($category->subCategory as $subcategory)
{!!$subcategory->title!!} {!! $subcategory->itemCount !!}
#endforeach
</p>
View Category
#endforeach
This is sample of the records in category table there are column
id | title | parent
1 Main cat 0
2 Sub-Cat 1
3 Sub-Cat 2 1
4 Main cat 2 0
So each parent is 0 and each child(sub category) has the parent ID
item table has also reference to category table -> column category_id
I can't figured it out how to make the condition if no items and no childs to not show it on page.
In Controller
$allCategories = Category::where('parent_id', 0)->has('children.item')
->with(['children'=> function($query){
$query->withCount('item');
}])
->get()
->each(function($parentCategory){
// if you wants calculate sum child category item count and assign to parent category item_count.
$parentCategory->item_count = $parentCategory->children->sum(function ($child) { return isset($child->item_count)?$child->item_count:0;});
});
return view('frontend.home', compact('allCategories'));
In this query only one query will be executed and it return all of your needs.
And In Blade View file
#foreach($allCategories as $category)
{!!$category->title!!} ({!! $category->item_count!!})
<p class="card-text">
#foreach($category->children as $subcategory)
{!!$subcategory->title!!} {!! $subcategory->item_count !!}
#endforeach
</p>
View Category
#endforeach
I'm facing an issue to order products by price related to category. When I click "sort by price" it shows all products from all categories ordered by price. I need to present only the products that relate to the category that is in the url, ordering by price.
This is the controller:
class SortController extends MainController{
public function sortBy($category_url, Request $request)
{
$sort = $request->get('sort', 'asc');
$products = Product::orderBy('price', $sort, $category_url)->get();
return view('content.sort')->with('products', $products);
}
}
This is the view:
extends('master')
#section ('content')
<form id="order-product-form" method="get" action=">>
{{url('shop/{category_url}/sort=ASC')}}"enctype="multipart/form-data">
#if ($products)
#foreach($products as $product)
{{ $product['title']}}
To filter a model based on a related model you use whereHas()
$products = Product::whereHas('category', function ($query) {
return $query->where('id', '=', $category_id); // You filter here by the required category
});
$products->orderBy('price', $sort, $category_url)->get();
You need $category->products->title.
Do you have a relation between models Category and products?
I was wondering what the cleanest way was to count the number of posts that are connected to a category in my blog.
Here is how the table relationship is set up.
What I have is a hasMany relationship from the Category to the Post models like this:
In Categories Model
public function blog_posts()
{
return $this->hasMany('App\Http\Models\Blog_Post', 'category_id');
}
And in the Blog_Post Model
public function blog_categories()
{
return $this->belongsTo('App\Http\Models\BlogCategories', 'category_id');
}
In effect all I want to do is be able to return to my view the total number of posts that each category has as shown below. Where x is the number of posts within each category.
cat1 (x)
cat2 (x)
cat3 (x)
It's not hard to count I know however as I only want a count I do not want to also retrieve the records as they are not required and I also do not want to create more queries than is necessary.
I have not completed the view as yet but probably a start would be to pass through the categories in a loop to display each and add the count at the same time?
#foreach ($categories as $category)
{!! $category->name !!} - {!! Count of posts here !!}
#endforeach
Hopefully that is clear(ish)!
Eager load the relation in your controller:
public function index()
{
$categories = Category::with('blog_posts')->get();
return view('categories.index', compact('categories'));
}
You can then use the count() method on the blog_posts relation when looping over categories in your view:
#foreach ($categories as $category)
<li>{{ $category->name }} ({{ $category->blog_posts->count() }})</li>
#endforeach
EDIT: Since Laravel 5.3, you can use withCount() to load counts of relations, i.e.
$categories = Category::withCount('blog_posts')->get();
This will make the count available via a property:
foreach ($categories as $category) {
$blog_posts_count = $category->blog_posts_count;
}
The nicest way to do it with eager loading support I know is to create a separate relation with the post count. Check this out:
public function blog_posts_count() {
return $this->hasOne('App\Http\Models\Blog_Post', 'category_id')
->selectRaw('category_id, count(*) as aggregate')
->groupBy('category_id');
}
public function getBlogPostsCountAttribute() {
if(!array_key_exists('blog_posts_count', $this->relations))
$this->load('blog_posts_count');
$related = $this->getRelation('blog_posts_count');
return $related ? (int) $related->aggregate : 0;
}
Usage is simple:
{{ $category->blog_posts_count }}