Laravel Relationship Query to load hasMany + BelongsToMany - php

I need to get brands data in specific collection page but only has more than 1 product.
Here are relations between models.
Brand -> HasMany -> Product
Product <= BelongsToMany => Collection
I was able to get brands data that have more than 1 products for all collections as following:
$brands = Brand::has("products")->get(); //this will return all brands that have more than 1 product.
Now I need to add collection limitation here.
I can get collection from $slug for specific page.
$collection = Collection::where("slug", $slug)->first();
Can anyone please help me how to get brands for specific collection page?

Try this:
$brands = Brand::has("products")
->whereHas('products.collections',function($q) use ($slug){ // your relation to product model
$q->where("slug", $slug);
})
->get();

Related

How to return model with relationsip in laravel?

I have two model Product and Category.
The categories table have id, and name columns.
While the products table have id, name, and category_id [foreign_key to category].
Here is my below code (already have category with values of 1, "School Supply"):
$product = new Product;
$product->category_id = 1;
$product->name = "pencil";
$product->save();
return $product->with('category');
My question is why it returns an error below when I try to get the data with the relation model? Someone knows how to do it exactly?
[34;4mIlluminate\Database\Eloquent\Builder[39;24m {#4069}
You can lazy eager load the relations using load method instead of with.
with is used for eager loading.
$product->load('category');
return $product;

Laravel collection get occurrences of a MtoM relation

this is my situation:
I have a collection of products and i want all the categories of those products.
Between Product and Category there is a many-to-many relation already created, and i want to do something like this:
$prods = Product::where(something)->get();
$categories = $prods->categories();
But obviously this doesn't work, and i would avoid getting all categories for each products, and add it to a collection only if is not alredy in it... something like this:
select *
from categories join pivot on categories.id = pivot.id
where pivot.product_id IN (1,2,3,4,5)
where 1,2,3,4,5 are the ids of the products
Is there any way to do it without QueryBuilder (using Eloquent)?
You should define a many-to-many relationship in your Product model
public function categories()
{
return $this->belongsToMany(Category::class);
}
And then you can do this
$ids = [1,2,3,4,5];
$prods = Product::with('categories')->findOrFail($ids);
$categories = $prods->flatMap->categories;
The with call eager loads your categories, and then you retrieve them easily + flatten (to avoid multi-dimensional collection) thanks to flatMap method.

Getting id of products that belong to category

I have model many-to-many (including pivot table). I need to pull out only the products that belongs to a certain category. I'm trying this but it gives me all the products:
$products = User::whereHas('category', function ($query) {
$query->where('id','1');
})->get();
1 in where is just for testing because when I put $id that was defined outside query it doesn't recognize it.
Try this.
$products= User::whereHas('category', function ($query) use ($id) {
$query->where('id', $id);
})->get();
Maybe the fetchProducts method here will shed some light: Getting product brands, their categories and associated products

laravel 5.2 many to many relation retrieve data with intermediate table

I have tables :
products
id
categories
id
product_category
product_id
category_id
by using eloquent model relation, how to get all product data from a specific category id?
Assuming that you defined relationships on your models, you can try this:
$productName = 'Some product';
$category = Category::findOrFail($categoryId);
$product = $category->products->where('product_name', '=', $productName)->get();

Inner join single column using Eloquent

I am trying to get a single column of an inner joined model.
$items = Item::with('brand')->get();
This gives me the whole brand object as well, but I only want brand.brand_name
$items = Item::with('brand.brand_name')->get();
DidnĀ“t work for me.
How can I achieve this?
This will get related models (another query) with just the column you want (an id, see below):
$items = Item::with(['brand' => function ($q) {
$q->select('id','brand_name'); // id is required always to match relations
// it it was hasMany/hasOne also parent_id would be required
}])->get();
// return collection of Item models and related Brand models.
// You can call $item->brand->brand_name on each model
On the other hand you can simply join what you need:
$items = Item::join('brands', 'brands.id', '=', 'items.brand_id')
->get(['items.*','brands.brand_name']);
// returns collection of Item models, each having $item->brand_name property added.
I'm guessing Item belongsTo Brand, table names are items and brands. If not, edit those values accordingly.
Try this:
$items = Item::with(array('brand'=>function($query){
$query->select('name');
}))->get();

Categories