Laravel Many to Many Query - laravel

So I have a products table and a categories table and a pivot table.
Product (products)
-- id
-- name
Category (categories)
-- id
-- name
CategoryProduct (category_product)
-- category_id
-- product_id
I want to get all products that belong to a certain category, I have managed to get it by doing the following query:
$products = Category::find(3)->products;
But how can I access it off the product model?
$products = Product::?

You need the whereHas clause. https://laravel.com/docs/5.4/eloquent-relationships#querying-relationship-existence
$products = Product::whereHas('categories', function ($query) {
return $query->where('id', 3);
})->get();
Or you can do it with a join instead.
$products = Product::select('products.*')
->join('category_product', 'products.id', '=', 'category_product.product_id')
->where('category_product.category_id', 3)
->groupBy('products.id')
->get();

Related

How do I query data from a pivot table in Laravel 7 [duplicate]

Searching from pivot table using laravel.
Here is my table structure:
Product
id
name
Categories
id
name
product_category (Pivot table)
id
category_id
product_id
//products can have multiple categories
Product model:
public function categories(){
return $this->belongsToMany(Category::class, 'product_category');
}
What is the best way to search all products by category id?
Currently I am doing this way, and it seems not an efficient way:
//Controller
$categories = product_category::where('category_id',1)->get();
Now I have to loop through categories and then get Products and pass it to views? Any idea how to do this in an efficient way?
For this you could use the whereHas() method:
$categoryId = 1;
$products = Product::whereHas('categories', function ($query) use($categoryId) {
$query->where('id', $categoryId);
})->get();
The above will return all products that are in the Category where the id is equal to $categoryId.
You can eager load products for a given category. Try:
$category = Category::with('products')->where('category_id',1)->find(1);
When you do this, only 2 database queries will be executed: one for loading the category, and one for loading related products.
Then in your Blade view you can do:
#foreach($category->products as $product
{{ $product->name }}
#endforeach
You can use this inside your method in controller..this only works when $request->$query(search) have value .then here we use wereHas for get the relationship of model and with->() using for get pivot table values
->when($request->query('search'), function ($query)use($request) {
$q= $request->query('search');
return $query->whereHas('relation name', function (Builder $query) use ($q) {
$query->with('pivot table name.column name')
->where('pivot table name.column name', 'like', "%{$q}%")
});})

How to count the orders of one product?

I have products , orders and third pivot table product_order(product_id , order_id), I need to count the orders of the product based on created_at
my shut:
public function product_chart(Product $product)
{
$orders = $product->whereHas('orders', function ($query) {
$query->whereMonth('created_at', '04');
})->count();
dd($orders);
}
The output gives the number of products :(
of course, I have a relation in a product called (orders) and in Order called (products)
So I need to count the orders of the product based on the created_at of order!
That's because you are counting the products.
You can simply do this:
$ordersCount = $product->orders()->count();
But since you are applying some conditions, you need to append the where clause:
$ordersCount = $product->orders()->whereMonth('created_at', '04')->count();
Also there's a simpler way doing it according to Laravel Documentation:
use Illuminate\Database\Eloquent\Builder;
$posts = App\Post::withCount(['votes', 'comments' => function (Builder $query) {
$query->where('content', 'like', 'foo%');
}])->get();
echo $posts[0]->votes_count;
echo $posts[0]->comments_count;

how to make join in laravel ? get only some columns of another table

I am working on admin panel ... where i get all products from database and show in table ... the problem is i want to get each product categorey from "category" table and get stock of each product from "products attribute" table ... i am create a join but this join collapse product id , name stock or prize from another table... Thanks.
public function viewProducts(Request $request){
$products = Product::get();
$products = Product::join('categories','categories.id','products.category_id')
->join('products_attributes','products_attributes.product_id',
'products.id')
->get();
$products = json_decode(json_encode($products));
//echo "<pre>"; print_r($products); die;
return view('admin.products.view_products')->with(compact('products'));
}
$products = Product::join('categories','categories.id','products.category_id')
->join('products_attributes','products_attributes.product_id','products.id')
->get(['categories.category_name as category_name', 'products_attributes.stock as product_stock', 'products.*']);
Try this:
Product::join('categories','categories.id','products.category_id')
->join('products_attributes','products_attributes.product_id','products.id')
->select(['categories.category_name as category_name', 'products_attributes.stock as product_stock', 'products.*'])
->get()->toArray();

best approach to search from pivot table using laravel

Searching from pivot table using laravel.
Here is my table structure:
Product
id
name
Categories
id
name
product_category (Pivot table)
id
category_id
product_id
//products can have multiple categories
Product model:
public function categories(){
return $this->belongsToMany(Category::class, 'product_category');
}
What is the best way to search all products by category id?
Currently I am doing this way, and it seems not an efficient way:
//Controller
$categories = product_category::where('category_id',1)->get();
Now I have to loop through categories and then get Products and pass it to views? Any idea how to do this in an efficient way?
For this you could use the whereHas() method:
$categoryId = 1;
$products = Product::whereHas('categories', function ($query) use($categoryId) {
$query->where('id', $categoryId);
})->get();
The above will return all products that are in the Category where the id is equal to $categoryId.
You can eager load products for a given category. Try:
$category = Category::with('products')->where('category_id',1)->find(1);
When you do this, only 2 database queries will be executed: one for loading the category, and one for loading related products.
Then in your Blade view you can do:
#foreach($category->products as $product
{{ $product->name }}
#endforeach
You can use this inside your method in controller..this only works when $request->$query(search) have value .then here we use wereHas for get the relationship of model and with->() using for get pivot table values
->when($request->query('search'), function ($query)use($request) {
$q= $request->query('search');
return $query->whereHas('relation name', function (Builder $query) use ($q) {
$query->with('pivot table name.column name')
->where('pivot table name.column name', 'like', "%{$q}%")
});})

Laravel Relationships with 3 tables and two pivot tables

Hi I used Laravel relationships with many to many pivot tables without problems but i can't get around the logic i need to write to create a relation between 3 models using 2 pivot tables to execute a query like the one below:
select * from product
left join product_to_category on product_to_category.product_id = product.product_id
left join category on product_to_category.category_id = category.category_id
left join category_to_brand on category_to_brand.category_id = category.category_id
left join brand on brand.brand_id = category_to_brand.brand_id
where brand.key = 'furniture-hire-uk'
and category.slug = 'chair-hire'
the table structure is as follows:
product
product id
some more feilds
category
category id
some more feilds
brand
brand_id
key
some more feilds
product_to_category
product_id
category_id
category_to_brand
category_id
brand_id
Using relationships:
// assuming relations:
categories: Product belongsToMany Category
brands: Category belongsToMany Brand
// and tables according to your question:
product, category, brand
$slug = 'chair-hire';
$key = 'furniture-hire-uk';
Product::whereHas('categories', function ($q) use ($slug, $key) {
$q->where('category.slug', $slug)
->whereHas('brands', function ($q) use ($key) {
$q->where('brand.key', $key);
});
})->get();
Or manual joins:
Product::join('product_to_category as pc', 'product.id', '=', 'pc.product_id')
->join('category', function ($j) use ($slug) {
$j->on('category.id', '=', 'pc.category_id')
->where('category.slug', '=', $slug);
})
->join('category_to_brand as cb', 'category.id', '=', 'cb.category_id')
->join('brand', function ($j) use ($key) {
$j->on('brand.id', '=', 'cb.brand_id')
->where('brand.key', '=', $key);
})
->get(['product.*'])

Resources