<?php | |
/** | |
* You should read 👇 this great article for context. | |
* https://zaengle.com/blog/using-wherehas-in-laravel-polymorphic-relations | |
* | |
* This is an attempt to make the WhereHas queries dynamic | |
* so you don't need to specify a new method for each new type. | |
*/ | |
use App\Post; | |
use App\Event; | |
use App\Comment; | |
use Illuminate\Database\Eloquent\Relations\Relation; | |
/** | |
* Basic usage | |
*/ | |
$events = Event::whereEventable(Post::class, function ($query) { | |
$query->wherePublished(); | |
})->get(); | |
/** | |
* Can add another class into the mix *without* changing the the Event class 🎉 | |
*/ | |
$events = Event::whereEventable(Post::class, function ($query) { | |
$query->wherePublished(); | |
})->orWhere->whereEventable(Comment::class, function ($query) { | |
$query->etc(...); | |
})->get(); | |
/** | |
* Can also use morph mapped values | |
*/ | |
Relation::morphMap(['posties' => Post::class]); | |
$events = Event::whereEventable('posties', function ($query) { | |
$query->wherePublished(); | |
})->get(); |
<?php | |
namespace App; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Database\Eloquent\Relations\Relation; | |
class Event extends Model | |
{ | |
protected $guarded = []; | |
public function scopeWhereEventable($query, $type, $callback) | |
{ | |
$this->filterPolymorphicRelation($query, 'eventable', $type, $callback); | |
} | |
protected function filterPolymorphicRelation($query, $name, $type, $callback) | |
{ | |
$class = Relation::getMorphedModel($type) ?? $type; | |
$query->where("{$name}_type", '=', $type) | |
->whereIn("{$name}_id", function ($query) use ($class, $callback) { | |
$model = new $class; | |
$query = $model->newEloquentBuilder($query)->setModel($model); | |
$callback($query); | |
$query->select([$model->getKeyName()]); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment