Martin S
Martin S

Reputation: 428

Laravel Intersection of Model Data

I have Article and Tag models with corresponding functions in each files:

Article.php:

public function tags()
    {
        return $this->belongsToMany('App\Tag')->withTimestamps();
    }

Tag.php:

public function articles()
    {
        return $this->belongsToMany('App\Article');
    }

On Blade view, I can access articles with a corresponding tag by calling

@foreach($tag->articles as $article)
   ...
@endforeach

From above, I can access a number of articles for a single tag. How can we filter articles with multiple tags, say only articles which have both tag1 and tag2 in a Tag model?

Upvotes: 3

Views: 1951

Answers (1)

Tomas Buteler
Tomas Buteler

Reputation: 4117

This is the native way of doing what you want:

$tags = ['tag1', 'tag2'];
$articles = Article::whereHas('tags', function ($query) use ($tags) {
    $query->whereIn('tag', $tags);
})->get();

If you want, you can use dynamic query scopes to make it slightly more readable:

// Article.php

public function scopeTagged($query, $tags)
{
    $query->whereHas('tags', function ($q) use ($tags) {
        $q->whereIn('tag', (array)$tags);
    });
}

That way you could do this when querying articles:

Article::tagged('tag1')->get();
Article::tagged(['tag1', 'tag2'])->get();

Upvotes: 3

Related Questions