7
votes

In the documentation of Eloquent it is said that I can pass the keys of a desired relationship to hasManyThrough.

Lets say I have Models named Country, User, Post. A Country model might have many Posts through a Users model. That said I simply could call:

$this->hasManyThrough('Post', 'User', 'country_id', 'user_id');

This is fine so far! But how can I get these posts only for the user with the id of 3 ?

Can anybody help here?

3
Setup relation on the User model and get posts for the user you want. Or query the relation using has method. Or use query builder.. Ask precise question to get accurate answerJarek Tkaczyk
Honestly all your suggestions sound interesting. I am just looking for a way to accomplish that and do not know how to ask more precisly =(user3518571

3 Answers

5
votes

So here it goes:

models: Country has many User has many Post

This allows us to use hasManyThrough like in your question:

// Country model
public function posts()
{
  return $this->hasManyThrough('Post', 'User', 'country_id', 'user_id');
}

You want to get posts of a given user for this relation, so:

$country = Country::first();
$country->load(['posts' => function ($q) {
  $q->where('user_id', '=', 3);
}]);
// or
$country->load(['posts' => function ($q) {
  $q->has('user', function ($q) {
    $q->where('users.id', '=', 3);
  });
})

$country->posts; // collection of posts related to user with id 3

BUT it will be easier, more readable and more eloquent if you use this instead: (since it has nothing to do with country when you are looking for the posts of user with id 3)

// User model
public function posts()
{
  return $this->hasMany('Post');
}

// then
$user = User::find(3);
// lazy load
$user->load('posts');
// or use dynamic property
$user->posts; // it will load the posts automatically
// or eager load
$user = User::with('posts')->find(3);

$user->posts; // collection of posts for given user

To sum up: hasManyThrough is a way to get nested relation directly, ie. all the posts for given country, but rather not to search for specific through model.

3
votes
$user_id = 3;

$country = Country::find($country_id);

$country->posts()->where('users.id', '=', $user_id)->get();
3
votes

$this->hasManyThrough('Post', 'User', 'country_id', 'user_id')->where(column,x);

What happen here is you get the collection in return you can put any condition you want at the end.