Search code examples
phplaravel-5many-to-manypolymorphic-relationship

How to build Eloquent query to retrieve records of the main table, applying where clause on it's related table in Laravel 5 PHP?


Using the sample many-to-many polymorphic relaltionshiop database structure from Laravel documentation as following:

posts
  id - integer
  name - string

videos
  id - integer
  name - string

tags
  id - integer
  name - string

taggables
  tag_id - integer
  taggable_id - integer
  taggable_type - string

I would like to retrieve post records where post.name LIKE %laravel% OR tags.name LIKE %laravel%.

How to use Eloquent model to build such query? It is a big challenge to me, since I want to only get posts which their name consists of word laravel OR any posts which their related tags have name consisting of the same word.


Solution

  • You can use whereHas for this.

    From the docs:

    If you need even more power, you may use the whereHas and orWhereHas methods to put "where" conditions on your has queries. These methods allow you to add customized constraints to a relationship constraint, such as checking the content of a comment

    use Illuminate\Database\Eloquent\Builder;
    
    // Retrieve posts with at least one comment containing words like foo%...
    $posts = App\Post::whereHas('comments', function (Builder $query) {
        $query->where('content', 'like', 'foo%');
    })->get();
    

    In your case it would be something like this:

    use Illuminate\Database\Eloquent\Builder;
    
    $input = 'laravel';
    
    Post::whereHas('tags', function (Builder $query) use ($input) {
        $query->where('name', 'like', '%' . $input .'%');
    })->orWhere('name', 'like', '%' . $input . '%')->get();