Skip to content

Instantly share code, notes, and snippets.

@timacdonald
Last active August 30, 2020 09:28
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save timacdonald/128e7d150f7214b51a030193d3d2b937 to your computer and use it in GitHub Desktop.
Save timacdonald/128e7d150f7214b51a030193d3d2b937 to your computer and use it in GitHub Desktop.
<?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()]);
});
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $guarded = [];
public function scopeWherePublished($query)
{
$query->where('published_at', '<=', now());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment