'How to check relation data of a collection before sending it to view
I have a Controller method like this:
public function awaiting()
{
$producers = Producer::where('producer_process',4)->get();
$producers_list = [];
foreach($producers as $producer){
if($producer->brand->brand_rejected == 0){
array_push($producers_list, $producer);
}
}
return view('admin.brands.awaiting', compact('producers_list'));
}
So basically there's One To One relationship between Producer model & Brand model.
In order to get the collection of brands table records that has producer_process of 4 and ALSO the brand_rejected field of related brands table record must be set to 0, I added an array_push and check the condition.
Now this works fine and properly shows the correct data but I wanted to know, what is the shorthand method of doing this with Eloquent relationships?
I mean is there any concise and useful method written in Eloquent relationships that can do this without using array_push or another foreach loop?
Solution 1:[1]
You can use whereHas to constrain the result set based on the existence of a relationship. Here we are saying we only want producers that have the field 'produce_process' set to 4 and have a brand with a field of 'brand_rejected' set to 0:
$producers = Producer::where('producer_process', 4)
->whereHas('brand', function ($q) { $q->where('brand_rejected', 0); })
->get();
If you want these producers to have their brand relationship loaded to use you should eager load that. Before the get call you can tell it to load the relationship:
$producers = Producer::where(...)->whereHas(...)->with('brand')->get();
Laravel 5.8 Docs - Eloquent - Relationships - Querying Relationship Existence whereHas
Laravel 5.8 Docs - Eloquent - Relationships - Eager Loading with
Solution 2:[2]
You can try this:
public function awaiting()
{
$producers = Producer::where('producer_process',4)
->with('brand', function($q) {
$q->where('brand_rejected', 0);
})->get();
// dd($producers);
dd($producers->pluck(brand));
Solution 3:[3]
Sure you can use the method with() also with the where() clause to can apply some conditions to the relationship
Example
$yourQuery->with('brand', function($query){
$query->where('brand_rejected', 0);
});
check this for more info
https://laravel.com/docs/9.x/eloquent-relationships#constraining-eager-loads
I hope it's helpful
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | lagbox |
| Solution 2 | Maik Lowrey |
| Solution 3 | Ahmed Hassan |
