This commit is contained in:
2026-06-13 16:51:50 +03:30
parent 1ffd920e89
commit 12fc305045
+30 -22
View File
@@ -3,7 +3,6 @@
namespace App\Traits;
use App\Models\SavedItem;
use Illuminate\Database\Eloquent\Relations\MorphMany;
trait HasSaves
{
@@ -11,49 +10,58 @@ public function saves()
{
return $this->morphMany(SavedItem::class, 'saveable');
}
public function getIsSavedAttribute()
{
if (!auth()->check()) return false;
return $this->saves()
->where('user_id', auth()->id())
->exists();
return $this->isSavedByAuthUser();
}
public function getSavedCountAttribute()
{
return $this->saves()->count();
}
// Check the saves() relation directly (not the is_saved attribute, which a
// model may override to point at a different table — e.g. Media), so toggle
// always decides against the same table it writes to.
protected function isSavedByAuthUser(): bool
{
if (!auth()->check()) {
return false;
}
return $this->saves()->where('user_id', auth()->id())->exists();
}
public function toggleSaveStatus()
{
if ($this->getIsSavedAttribute()) {
return $this->removeSave();
} else {
return $this->addSave();
}
return $this->isSavedByAuthUser() ? $this->removeSave() : $this->addSave();
}
public function addSave()
{
if ($this->getIsSavedAttribute()) return false;
return SavedItem::create([
if (!auth()->check()) {
return false;
}
// Idempotent: never inserts a duplicate even on repeated/racing calls.
return SavedItem::firstOrCreate([
'user_id' => auth()->id(),
'saveable_id' => $this->id,
'saveable_type' => get_class($this),
]);
}
public function removeSave()
{
if (!$this->getIsSavedAttribute()) return false;
if (!auth()->check()) {
return false;
}
return SavedItem::where([
'user_id' => auth()->id(),
'saveable_id' => $this->id,
'saveable_type' => get_class($this),
])->delete();
}
}
}