Robo Robok
Robo Robok

Reputation: 22815

Additional many to many relations in Laravel

is there any way in Laravel 5 to make our belongsToMany() method get more relations than described in pivot table? I'd like to have my $user->movies() method retrieve movies assigned to the user and all movies with access column set to public. Is that possible without manual query?

I tried this:

public function movies() {
    return $this->belongsToMany('App\Movie')->orWhere('access', 'public')->withTimestamps();
}

But it doesn't seem to work. How can it be done?

Upvotes: 1

Views: 95

Answers (1)

lukasgeiter
lukasgeiter

Reputation: 153140

That is not possible this way. You can do this though:

$userId = 1;
$movies = App\Movie::whereHas('users', function($q) use ($userId){
    $q->where('user_id', $userId);
})->orWhere('access', 'public')->get();

You can put the whole thing inside your User model inside an attribute accessor but you won't be able to eager load it.

public function getAvailableMoviesAttribute(){
    $userId = $this->getKey();
    $movies = App\Movie::whereHas('users', function($q) use ($userId){
        $q->where('user_id', $userId);
    })->orWhere('access', 'public')->get();
    return $movies;
}

Usage:

$user = User::find(1);
$user->availableMovies;

To be able to do more filtering you can use a "normal" function in your model and just return the query without calling get()

public function movies(){
    $userId = $this->getKey();
    return App\Movie::whereHas('users', function($q) use ($userId){
        $q->where('user_id', $userId);
    })->orWhere('access', 'public');
}

Usage:

$user->movies()->where('title', 'LIKE', B%')->get()

Note that now movies isn't a relationship anymore. It's just a function that returns a query builder instance.

Upvotes: 2

Related Questions