fetch related records between 3 model - php

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();

Related

Show only the latest category of product in Laravel 5.8

I have three models: products, category, product_category. A product may have many categories, and some categories may have a parent. You can find related relations below. I could show all categories with a foreach() loop, but I don't want to do that. I wish only to show the category, and it must be the latest. Is there a way to show only the last category of a parent category of the current product?
<div class="row">
#foreach ($products as $product)
#foreach ($product->categories as $cat)
{{ $cat->title }}
#endforeach
#endforeach
</div>
Product model
public function categories()
{
return $this->belongsToMany(Category::class);
}
Category model
public function products()
{
return $this->belongsToMany(Product::class);
}
public function subcategories()
{
return $this->hasMany('\App\Category', 'parent_id');
}
public function parent()
{
return $this->belongsTo('\App\Category', 'parent_id');
}
Categories schema
$table->increments('id');
$table->string('title');
$table->integer('parent_id')->nullable();
Category_product schema
$table->increments('id');
$table->integer('category_id')->unsigned();
$table->integer('product_id')->unsigned();
You can use query builder on the relationship like so:
$product->categories->orderBy('id', 'desc')->first();
That will order from most recent to oldest and you can just take the first record.
You can simply use
$product->categories()->orderBy('id', 'DESC')->first();
Or you can also try
public function categories()
{
return $this->belongsToMany(Category::class)->orderBy('id','DESC');
}
Then you can use
$product->categories()->first();
Using specific methods on your model
Your categories definition would be something like this, right?
public function categories() {
return $this->belongsToMany(Category::class);
}
So, just create another method to retrieve only the latest.
public function latestCategory() {
return $this->categories()->latest();
}
If you need the oldest category, the same approach is applied.
public function oldestCategory() {
return $this->categories()->oldest();
}
Using only the categories relationship definition
You could also apply a different approach if you do not intend to create new methods:
$this->categories()->latest();
or
$this->categories()->oldest();
Hope it will help you.
Have a great day.
You can use latest() method
$product->categories->latest()->first();
Or,
$product->categories->orderBy('id', 'desc')->first();

How to use eloquent to retrieve a column from another table

I have two tables
product: id|category ...
category: id|name ...
product.category is a foreign key linked to category.id . I am building a basic CRUD and I would like to display all Products in the the product table as well as the name of the category they belong to rather than their category ID. TO do this, while searching the laravel documentation I came across the query builder and I achieved my goal.
public function index()
{
$products = \DB::table('products')
->join('categories', 'products.category', '=', 'categories.id')
->select('*')
->get();
return view('product' ,compact('products'));
}
Under my models for product and category I have created the appropriate relationships.
product.php :
public function category()
{
return $this->belongsTo('App\Category');
}
category.php :
public function products()
{
return $this->hasMany('App\Product');
}
I keep hearing about the power of Eloquent and was wondering how I could achieve a similar result with eloquent and if eloquent is designed for such operations or if the query builder is the right way to go.
Every tutorial online seems to only use the post and comments scenario of getting all comments belonging to a post.
You can use this code
public function index()
{
$products = Product::with('category')->get();
return view('product' ,compact('products'));
}
In blade
#foreach($products as $product)
{{$product->name}}
{{$product->category->name ?? ''}}
//or
#if ($product->category)
$product->category->name
#endif
#endforeach
Also if in project table foreign key is not equal category_id. In your case
public function category()
{
return $this->belongsTo('App\Category', 'category');
}

Laravel cross check query

I want show my brands page like: url/discount/{brand-slug} so far i can get it done by something like:
$brandspromotion = Brand::where('slug', $slug)->OfStatus('Active')->firstOrFail();
problem occurs when I try to get only products with same brand_id which their id is saved in 3rd table named discounts.
In the simple words: I want to get only discounted products of each brand.
LOGIC
Discounts table saves product_id
Products table saves brand_id
Brand has to find it's own id from products through discounts table.
Code
so far I have this code, which is not working :)
public function brandspromotions($slug) {
$promotions = Discount::Valid()->get();
$grouped = $promotions->map(function ($item, $key) {
return $item->products->brand_id;
});
$brandspromotion = Brand::where('slug', $slug)->OfStatus('Active')
->where('id', $grouped)->get();
return view('front.brandspromotions', compact('brands', 'brandspromotion'));
}
UPDATE
product model
public function discount(){
return $this->belongsTo(Discount::class, 'product_id', 'id');
}
public function brand(){
return $this->belongsTo(Brand::class);
}
brand model
public function products(){
return $this->hasMany(Product::class);
}
discount model
public function products(){
return $this->belongsTo(Product::class, 'product_id', 'id');
}
If you have a brand slug and you want to get only products of this brand which have a record in the discounts table:
Product::has('discount')
->whereHas('brand', function($q) use($slug) {
$q->where('slug', $slug);
})
->get();
Where discount and brand are the relationships defined in the Product model.

Laravel-5 whereHas Clause dosen't work as expected

I have categories and products tables. They are related with Many to Many relationships.. I want to get products by categories and selected price range but whereHas clause dosen't work
$products = Product::whereHas('categories',function ($query) use ($slug){
$query->where('category_slug',$slug);
})->whereBetween('price',[100,200])->get();
Category Model;
public function products(){
return $this->belongsToMany('App\Product','category_product','category_id','product_id');
}
Product Model;
public function categories() {
return $this->belongsToMany('App\Category','category_product','product_id','category_id');
}
So, what is my mistake in here ?

Filter products by category filters, create dynamic filter with using category filter for get products, products have more filters

Tables
products:
-id
-status
-name_product
filters:
-id
-name
-category_filter_id
category_filters:
-id
-name
category_product (pivot table):
-id
-product_id
-filter_id
//Model Product
public function filters()
{
return $this->belongsToMany(Filter::class);
}
//Model Filter
public function products()
{
return $this->belongsToMany(Product::class);
}
public function categoryfilter()
{
return $this->belongsTo('App\CategoryFilter', 'categ_filter_id');
}
//Model CategoryFilter
public function filters()
{
return $this->hasMany('App\Filter');
}
How to get the products if the user chooses the following:
If check: model 1, model 2, tip 2 -> the result must be: product in Model (model 1 AND/OR model 2 AND tip 2) ??
I using select:
$filter_ids = [23,12,43];//id filters
$products = Product::where('status', "=", 1);
$products = $products->whereHas('filters', function($query) use ($filter_ids){
$query->whereIn('categ_filter_id', $filter_ids);
});
But if return the product which is at least once in the table pivot, but I need to return all the logical results.
Finally, I have to return the following: the products found in model_1 and type_2 but also the products in model_2 and type_2.
Please help me...
This dynamic filter has many categories, he need to work as a normal filter(logical).....
What do I have to do, or what is wrong?

Categories