Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel / Eloquent : hasManyThrough WHERE

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?

like image 509
user3518571 Avatar asked Jun 24 '14 14:06

user3518571


3 Answers

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.

like image 187
Jarek Tkaczyk Avatar answered Nov 20 '22 18:11

Jarek Tkaczyk


$user_id = 3;

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

$country->posts()->where('users.id', '=', $user_id)->get();
like image 30
Taron Hambardzumyan Avatar answered Nov 20 '22 18:11

Taron Hambardzumyan


$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.

like image 3
f_i Avatar answered Nov 20 '22 18:11

f_i