How can I use whereHas in the morphTo relation laravel?

12,166

Solution 1

Laravel 5.8 include new features for querying polymorphic relations.

The whereHasMorph() make it possible to query polymorphic relationships with something like the following:

Comment::whereHasMorph('commentable', [Post::class, Video::class], function($query){
    $query->where('title', 'foo');
})->get();

Which produces following query:

select * from "comments"
where (
  (
    "commentable_type" = 'App\Post' and exists (
      select * from "posts" 
      where "comments"."commentable_id" = "posts"."id" and "title" = 'foo'
    )
  ) or (
    "commentable_type" = 'App\Video' and exists (
      select * from "videos" 
      where "comments"."commentable_id" = "videos"."id" and "title" = 'foo'
    )
  )
)

Solution 2

Solved

I add this method :

public function product()
{
    return $this->belongsTo(Product::class, 'favoritable_id')
        ->where('favorites.favoritable_type', Product::class);
}

in favorite model

And I change the laravel eloquent to be like this :

$query->whereHas('product', function ($query) use ($q) {
    $query->where('name', 'like', "%$q%");
});

It works

Share:
12,166

Related videos on Youtube

Success Man
Author by

Success Man

Updated on June 04, 2022

Comments

  • Success Man
    Success Man almost 2 years

    My product model like this :

    <?php
    ...
    class Product extends Model
    {
        ...
        protected  $fillable = ['name','photo','description',...];
        public function favorites(){
            return $this->morphMany(Favorite::class, 'favoritable');
        }
    }
    

    My favorite model like this :

    <?php
    ...
    class Favorite extends Model
    {
        ...
        protected $fillable = ['user_id', 'favoritable_id', 'favoritable_type'];
        public function favoritable()
        {
            return $this->morphTo();
        }
    }
    

    My laravel eloquent like this :

    $q = $param['q'];
    
    $query = Favorite->where('user_id', auth()->user()->id)
                     ->with('favoritable');
    
    if($q) {
        $query->whereHas('favoritable', function ($query) use ($q) {
            $query->where('name', 'like', "%$q%");
        });
    }
    
    $query = $query->paginate(5);
    
    return $query
    

    If the script executed, there exist error like this :

    Unknown column 'name'

    How can I solve this problem?

  • Tarek Adam
    Tarek Adam about 6 years
    Thanks for taking the time to come back and share the solution.
  • Dylan Glockler
    Dylan Glockler almost 4 years
    I tried using whereHasMorph which the docs suggest should work, but I get the error "Non-static method Illuminate\Database\Eloquent\Builder::whereHasMorph() should not be called statically" - this solution seems to work great though!