15

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?

moses toh
  • 12,344
  • 71
  • 243
  • 443

2 Answers2

34

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'
    )
  )
)
Hemerson Varela
  • 24,034
  • 16
  • 68
  • 69
13

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

moses toh
  • 12,344
  • 71
  • 243
  • 443
  • 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! – Dylan Glockler Jul 30 '20 at 13:33