app/Models/Tag.php
use Illuminate\Database\Eloquent\Relations\MorphToMany; final class Tag extends Model{ public function articles(): MorphToMany { return $this->morphedByMany(Article::class, 'taggable'); }}
use Illuminate\Database\Eloquent\Relations\MorphToMany; final class Tag extends Model{ public function articles(): MorphToMany { return $this->morphedByMany(Article::class, 'taggable'); }}
use App\Models\Tag;use Illuminate\Database\Eloquent\Relations\MorphToMany; trait HasTags{ public function tags() { return $this->tagsRelation; } public function syncTags(array $tags) { $this->save(); $this->tagsRelation()->sync($tags); $this->unsetRelation('tagsRelation'); } public function removeTags() { $this->tagsRelation()->detach(); $this->unsetRelation('tagsRelation'); } public function tagsRelation(): MorphToMany { return $this->morphToMany(Tag::class, 'taggable')->withTimestamps(); }}
use App\Helpers\HasLikes;use App\Helpers\HasTags; final class Thread extends Model{ use HasLikes; use HasTags; public static function feedByTagPaginated(Tag $tag, int $perPage = 20): Paginator { return static::feedByTagQuery($tag) ->paginate($perPage); } public static function feedByTagQuery(Tag $tag): Builder { return static::feedQuery() ->join('taggables', function ($join) { $join->on('threads.id', 'taggables.taggable_id') ->where('taggable_type', static::TABLE); }) ->where('taggables.tag_id', $tag->id()); }}
use App\Models\Like;use Illuminate\Database\Eloquent\Relations\MorphMany; trait HasLikes{ public function likesRelation(): MorphMany { return $this->morphMany(Like::class, 'likesRelation', 'likeable_type', 'likeable_id'); }}
use App\Helpers\HasLikes;use App\Helpers\HasTags; final class Article extends Model{ use HasLikes; use HasTags; protected $with = [ 'likesRelation', ];}
use App\Models\Article; final class CreateArticle{ private $tags; public function handle(): Article { $article = new Article([ 'title' => $this->title, 'body' => $this->body, 'original_url' => $this->originalUrl, 'slug' => $this->title, 'submitted_at' => $this->shouldBeSubmitted ? now() : null, ]); $article->syncTags($this->tags); return $article; }}
use App\Models\Article; final class LikeArticle{ public function handle(): void { if ($this->article->isLikedBy($this->user)) { throw CannotLikeItem::alreadyLiked('article'); } $this->article->likedBy($this->user); }}