Support the ongoing development of Laravel.io →
posted 10 years ago
Eloquent
Last updated 2 years ago.
0
$tags = ['a', 'b'];

$posts = Post::whereHas('tags', function($query) use($tags) {
    $query->whereIn('name', $tags);
});

Using Where In With An Array http://laravel.com/docs/queries

Last updated 2 years ago.
0

A ready to test route

Note: you'll need a tags.slug table field for this to work, and specify tags by the comma separated list of slugs in url.

/**
 * Sample route to retrieve posts which have
 * at least all of the specified, comma separated tags
 */
Route::get('tags/{cstags}', function ($cstags) {

    // transform url-provided comma separated tags
    $tags = explode(',', $cstags);
    array_walk($tags, 'trim');

    // we only want "posts" table fields for Eloquent model, thus "selectRaw"
    $posts = Post::selectRaw('posts.*')
        ->join('post_tag', 'post_tag.post_id', '=', 'posts.id')
        ->join('tags', 'post_tag.tag_id', '=', 'tags.id')
        ->whereIn('tags.slug', $tags)
        ->groupBy('posts.id')
        ->havingRaw('COUNT(posts.id)=?', [count($tags)])
        ->get();

    $output =
        'Found ' . $posts->count()
        . ' posts having at least all of the ['
        . implode(', ', $tags)
        . '] tags'
        . '<pre>'
        . print_r($posts, true)
        . '</pre>';

    return $output;
});
Last updated 2 years ago.
0

zenry said:

$tags = ['a', 'b'];

$posts = Post::whereHas('tags', function($query) use($tags) { $query->whereIn('name', $tags); });

Using Where In With An Array http://laravel.com/docs/queries

I tried this way first, but it retrieves posts that have at least one of the given tags, not all. Then I tried to apply the whereHas for each tags within a foreach loop, but it retrieves posts that have only the exact given tags.

marekmurawski said:

A ready to test route

Note: you'll need a tags.slug table field for this to work, and specify tags by the comma separated list of slugs in url.

/**
* Sample route to retrieve posts which have
* at least all of the specified, comma separated tags
*/
Route::get('tags/{cstags}', function ($cstags) {

   // transform url-provided comma separated tags
   $tags = explode(',', $cstags);
   array_walk($tags, 'trim');

   // we only want "posts" table fields for Eloquent model, thus "selectRaw"
   $posts = Post::selectRaw('posts.*')
       ->join('post_tag', 'post_tag.post_id', '=', 'posts.id')
       ->join('tags', 'post_tag.tag_id', '=', 'tags.id')
       ->whereIn('tags.slug', $tags)
       ->groupBy('posts.id')
       ->havingRaw('COUNT(posts.id)=?', [count($tags)])
       ->get();

   $output =
       'Found ' . $posts->count()
       . ' posts having at least all of the ['
       . implode(', ', $tags)
       . '] tags'
       . ''
       . print_r($posts, true)
       . '';

   return $output;
});

Although it's not fluent it seems interesting, but I don't get what's a slug and what is it supposed to store ?

Thank you both.

Last updated 2 years ago.
0

Slug is commonly referenced as a string which can be safely put into URL, essentially it's just a url-friendly representation of a string,

Laravel has a corresponding Str::slug method:

http://laravel.com/api/4.1/Illuminate/Support/Str.html#method_slug

So, you could assume slug == url-friendly name (in your case - url-safe tag name)

I'm aware it's not very neat approach, but as you noted it works. I'd also like to know if it's possible to handle that search more Eloquent way.

Last updated 2 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.