How toc create relations between category and subcategories - laravel

I have categories and subcategories tables
Table catgeories:
id
title
description
Table subcategories:
id
category_id
parent_category_id
Data for categories table:
Data for subcategories table
In my case any category has unlimited child categories. How to make relations Many To Many for models to get all categories and there subcategories?

I suggest you to keep the categories in same table like below
id
parent_id
name
1
0
parent cat
2
1
child cat
In the above table parent_id which has 0 value are the actual parent categories, and which has number are child categories, eg: child cate is child of parent cat, in this way you can implement infinite child categories. But Don't worry we can achieve the relations as you have done, please follow as below
Am Assuming categories and subcategories as model. In categories model write a relation as below
public function childCategories(){
return $this->hasMany('\App\subcategories','parent_category_id','id')
->join('categories','categories.id','=','subcategories.categories')
->select("categories.title",'subcategories.*');
}
After the when you calling the categories call it via with as below, you will get categories with related sub categories
$categories = categories::with('childCategories')->get();

To get the category or, the sub-category, you can use this
$allSubCategory = DB::table('sub_categories')->orderBy('id', 'DESC')
->join('categories', 'sub_categories.category_id', '=', 'categories.id')
->select('sub_categories.*', 'categories.category_name')
->get();
$allCategory = DB::table('categorys')->orderBy('id', 'DESC')
->join('sub_categories', 'categorys.category_id', '=', 'sub_categories.id')
->select('categorys.*', 'sub_categories.sub_category_name')
->get();

Related

laravel 8 use orderBy and withMax for order tables with another table

i want to orderby products with max price from details table.
products one to many relation with details table.
in laravel documentation we have aggregate methods like withMax ,withMin and withCount
. These methods will place a {relation}_{function}_{column} attribute on your resulting models.
now we only need to orderBy with this results.
$products = Product::withMax('details', 'price')
->orderBy('details_max_price' , 'desc')
->paginate(15);

Eloquent query distinct sub id

I have these models
I want to make a query that shows me all the products whose stock quantity> 0 and that does not repeat the products.
My query:
$stock_products_limit = Stock::distinct('product_id')->where('quantity', '!=', 0)->get();
This would be much easier using a size chart relating it to stocks ... but for now I don't have it
I need the model to return me, and then do a foreach:
#foreach($stock_products_limit as $stock_product)
#foreach($stock_product->product->product_images as $i=>$product_image)
...
#endforeach
...
#enforeach
In my models I have the hasMany and belongsTo relations made
How could I make the query? I've been trying the distinct, group by ... but nothing works for me. It only removes the ones with quantity 0 and repeats the product ID ...
Example of the query I want:
SELECT DISTINCT(stocks.product_id)
FROM stocks
INNER JOIN products ON stocks.product_id = products.id
WHERE quantity != 0
ORDER BY product_id
LIMIT 10;
Another example query (but LIMIT doesn't work with IN)
SELECT * from products where id in (SELECT DISTINCT(product_id)
FROM stocks
INNER JOIN products ON stocks.product_id = products.id
WHERE quantity != 0
ORDER BY product_id)
Instead of making the Stock model as the starting point, you might want to use the Product model. Then you don't even have to think about using DISTINCT. Let's use whereHas
return Product::whereHas('stocks', function ($query) {
$query->where('quantity', '>', 0);
})
->limit(10)
->get();

Laravel ordering and limit results of a left join

One to many relationships, each product has many prices
table products
id | name | slug | created_at | update_at
table prices
id | product_id | title | price | link
I want to get the data limit of product limit 20 table and order created_at and each product get the lowest price, order column price. I want to use the query builder.
i tried
$products = DB::table('products')
->leftJoin('prices', 'products.id', '=', 'prices.product_id')
->select('products.id', 'products.name')->distinct()
->selectRaw('max(prices.price) as price')
->groupby('products.id')
->orderby('products.updated_at')
->get();
but it get all products and table prices order column id
You can use Eloquent Like This
public function price() {
return $this->hasMany('App\model\Prices' , 'product_id' ,'id');
}
and get like this , It will give you the mapped price only for your specific product
$product = Product::with('price')
->where(do the stuffs)
->orderBy(do the stuffs)
->get();
Or you can use the callback as well in with()

Query on eloquent relationship

I have Book and Store models which have belongsToMany relationship.
In Book.php
public function stores(){
return $this->belongsToMany('App\Store')->withPivot('qty');
}
In Store.php
public function books(){
return $this->belongsToMany('App\Book')->withPivot('qty');
}
Now I just want to know the total number of books in store A and B together. How can I do it with eloquent ORM? I can get all books belonging to store A and B using whereHas but cannot go further to aggregate the qty field in the pivot table.
So you want the total qty of books by combination of store id and book id
The way you've described your DB structure, it looks like your pivot table has exactly these columns: book_id, store_id and qty
So all you really need to do is:
DB::table('book_stores')->get()

Group join in linq but only where childs is present

I have this simple query and I want to have a list of categories and for each category the number of products inside.
from category in categories
join product in products
on category.Id equals product.Category_Id into productsPerCategories
select new Categories
{
Category = category,
products = productsPerCategories.Count()
};
But if there is no products, I don't want the category to appear. With my current construct, there will be categories with no products inside. How can I achieve that?
Just add a condition
where productsPerCategories.Any()
or
where productsPerCategories.Count() > 0
So your query would be:
from category in categories
join product in products on category.Id equals product.Category_Id into productsPerCategories
where productsPerCategories.Any()
select new Categories
{
Category = category,
products = productsPerCategories.Count()
};

Resources