Reputation: 725
I have 4 models: posts
, users
, categories
, userCategories
.
posts
-users
have one-to-many relationship (one post belongs to a user).
posts
-categories
have one-to-many relationship (one post belongs to a category).
users
-userCategories
have one-to-many relationship (one user has many userCategories). userCategory has a rank
field which holds the performance of the user for the specific category.
I query some posts with this:
$posts = Post::with(array('user.userCategories')
)
->where('category_id', '=', $category_id)
->get();
After evaluating posts, I try to get the user's the userCategory rank
for the post's category.
$rank_of_the_post_owners = array();
foreach($posts as $post)
foreach($post->user->userCatergories as $userCategory)
if($userCategory->id == $post->category_id) {
$rank_of_the_post_owners [$post->id] = $userCategory->rank;
break;
}
}
}
To get rid of the code above, I want to query only related userCategory (for the post's category). So that, I want to access the rank information like user.userCategory->rank instead of the loop.
How can I do that?
Upvotes: 0
Views: 37
Reputation: 35180
When using with()
you can constrain the relationship by using a closure as the value and since you already have the $category_id
you could do something like:
$posts = Post::with(['user.userCategories' => function ($query) use ($category_id) {
$query->where('userCategories.id', $category_id);
}])
->where('category_id', '=', $category_id)
->get();
Then if you wanted to you could add an accessor to get the ranks for the posts:
public function getRankAttribute()
{
return $this->user->userCategories->sum('rank');
}
So to access the rank you would just need to:
$posts->first()->rank;
https://laravel.com/docs/5.4/eloquent-mutators#accessors-and-mutators
Hope this helps!
Upvotes: 1