Laravel filtering one to many relations - laravel

I have Product and Category models tied one to many.How to filter Products by category? In template i have
{{ $category->name }}
How to write function to filter Products with Category?
public function productsByCategory($category_id){
$products = Product:: ????
return view("layouts._productsByCategory", compact("products"));
Answer is
$products = Product::where('category_id', $category_id)->get();

You can use:
$products = Product::where('category_id', $category_id)->get();
or
$products = Product::whereHas('category', function($q) use ($category_id) {
$q->where('id', $category_id);
});
assuming you set category relationship in Product model.

You might find it easier to go via the category:
public function productsByCategory($category_id){
return view("layouts._productsByCategory", [
'products' => Category::with('products')->find($category_id)->products
]);
}

Related

Laravel Order Collection Through Double Relationships

I am sending a Vehicle to my blade template which has a relationship of products that displays all the products fitting a vehicle.
Vehicle.php
public function products() {
return $this->belongsToMany(Product::class, 'vehicle_product');
}
I am strugging to figure out how to order those products based on a 3rd relationship's (product_group()) priority attribute.
Product.php
public function product_group() {
return $this->belongsTo(ProductGroup::class);
}
Blade Template
#foreach ($vehicle->products->orderBy('product_group.priority') as $product)
...
Use sortBy instead of orderBy but you must have products and product_group on 'vehicle' before applying it.
$vehicle = Post::query()
->with([
'products' => fn($q) => $q->with('product_group')
])
->where('id', 1)
->first();
$vehicle->products
->sortBy(fn($product) => $product->product_group->priority)
->values()
->all();

Laravel groupBy multiple relations

i have the follow relations
Order -> orderItems (hasnmany)-> product (hasOne) -> product_category (hasOne)
I would like get all orders groupBy category product id. But i need help because my query is not working well.
My query:
$items = Order::orderBy("id", "desc")
->with("orderItems.product.product_category")
->get();
$groupByCategory = $items
->groupBy("orderItems.product.product_category.id");
Can you help me please?
You are not starting from the right Object.
Dealing with Eloquent, always start as you want your tree to look like ;
in your case :
Category->product->order, so your query would look like this :
$categories = Category::with([
'products.orderItems' => function($query){
$query->orderBy('id', 'desc');
}])->get();
Then :
foreach($categories as $category){
// $category->name
foreach($category->products as $product){
// $product->name
foreach($product->orderItems as $item){
// $item->name
}
}
}

How to show the category name for each articles?

I use many-to-many relation.
It is necessary to list the articles to which categories the post belongs, I did this with the help of the builder, since I do not know how to do this, via ORM.
I have three tables:
categories
-id
-name
images
-id
-image
-description
category_image (pivot table)
-id
-image_id
-category_id
public function getCategoryTitle($id)
{
$post = DB::table('category_image')
->where('image_id', '=', $id)
->get();
$categoryImage = $post->toArray()[0]->category_id;
$showCategory = DB::table('categories')
->where('id', '=', $categoryImage)
->get();
return $showCategory->toArray()[0]->name;
}
Now it turns out that for each article, there will be 2 more requests to the database, which is very bad.
output so
public function index()
{
$posts = Image::all();
return view('admin.posts.index', ['posts'=>$posts]);
}
I tried to get categories name with ->
#foreach($posts as $post)
<tr>
<td>{{$post->id}}</td>
<td>{{$post->description}}</td>
<td>{{$post->getCategoryTitle($post->id)}}</td>
<tr>
#endforeach
Image model
dd( $this->belongsToMany(
Category::class,
'category_image',
'image_id',
'category_id',
1
));
Is there any easy way to get category name for each image using relation.
in image model
public function categories(){
return $this->belongsToMany(Category::class)
}
in category model
public function images(){
return $this->belongsToMany(Image::class)
}
with() for eager loading, provides you to get categories in single query
$posts = Image::with("categories")->get();
foreach($posts as $post) {
foreach ($post->categories as $category){
$category->name
}
}
If your relationships are set up correctly with laravel you can use the shorthand ->with('categories') (name dependin on the name of your belongs to many function in your class) to grab the category row as well

Laravel 5.5 - How to fetch related products in many to many relation

I am developing a e-commerce website.
I have 3 tables
1.prodcts table
2.conditions table
3.condition_product table
A product can have many conditions.
particular condition belongs to many products.
Now I have a product which belongs to 3 conditions.
I want to get all related products which belongs to these 3 conditions.
How can i achieve this?
product.php
public function conditions(){
return $this->belongsToMany(Condition::class)->withTimestamps();
}
condition.php
public function products(){
return $this->belongsToMany(Product::class)->withTimestamps();
}
This is my code:
public function productDetails(Product $product)
{
$a = $product->id;
$relatedProducts = Product::whereHas('conditions.products', function($q) use($a) {
$q->where('id', $a);
})
->get();
return view('pages/product', compact('product','relatedProducts'));
}
But I am getting error.
Use the whereHas() method with nested relationships:
Product::whereHas('conditions.products', function($q) use($productId) {
$q->where('id', $productId);
})
->get();
This will give you products that have conditions of a specified product.
Alternatively, you could do this:
$conditionIds = Product::find($productId)->conditions->pluck('id');
$products = Product::whereHas('conditions', function($q) use($conditionIds) {
$q->whereIn('id', $conditionIds);
})
->get();
A good practice is to always specify witch table the 'id' field is referencing too, because if not, it could both reference the 'conditions' table or the 'products' table 'id' field :
$relatedProducts = Product::whereHas('conditions.products', function($q) use($a) {
$q->where('products.id', $a);
})
->get();
You could see this answer about SQL ambiguous column name.

How to get all item same category with Eloquent

Hi all,
I'm building an application in Laravel, I want to get all item in an article category without using this Eloquent.
My code is
$info = Article::find($article_id);
$cate_info = $info->article_categories()->first();
if($cate_info){
$same = Article::with(['article_categories' => function ($query) use ($cate_info){
$query->where('articles_category.ID' ,$cate_info->ID);
}])->where('ID' ,'!=' ,$article_id)->get();
}
And I get all articles. How to solve.
Article and Article_Category is in many to many relationship.
Thanks.
If you want to have all the articles of a particular article_categories you can use whereHas method, now suppose you have name as a field column in categories table, so you can have something like this:
public function getData(Request $request)
{
$category = $request->categoryName;
// $category = 'ABC Category';
$articles = Article::whereHas('article_categories', function($query) use($category) {
$query->where('name', 'like', '%'.$category.'%');
})->get();
return response()->json(['articles' => $articles], 200);
}
Hope this helps.

Resources