model = $model; $this->cache = $cache; $this->cacheTag = $this->getCacheTag(); $this->readRepositoryClass = $this->getReadRepositoryClass(); } abstract protected function getCacheTag(): string; abstract protected function getReadRepositoryClass(): string; protected function getReadRepository(): mixed { return app($this->readRepositoryClass); } protected function clearRelatedCache(Model $model): void { $this->getReadRepository()->clearCacheForModel($model); } protected function clearCollectionCache(Collection $models): void { foreach ($models as $model) { $this->clearRelatedCache($model); } } public function create(array $data): Model { $model = $this->model->create($data); $this->clearRelatedCache($model); return $model; } public function createMany(array $data): Collection { $models = $this->model->insert($data) ? $this->model->whereIn('id', $this->model->latest()->take(count($data))->pluck('id') )->get() : collect(); $this->getReadRepository()->clearCache(); return $models; } public function update(Model $model, array $data): bool { $result = $model->update($data); $this->clearRelatedCache($model); return $result; } public function updateById(int $id, array $data): bool { $model = $this->model->findOrFail($id); return $this->update($model, $data); } public function upsert(array $data, array|string $uniqueBy, ?array $update = null): Collection { $this->model->upsert($data, $uniqueBy, $update); // Clear all cache since upsert can affect multiple records $this->getReadRepository()->clearCache(); // Return the upserted records $uniqueValues = collect($data)->pluck($uniqueBy); return $this->model->whereIn($uniqueBy, $uniqueValues)->get(); } public function delete(Model $model): bool { $result = $model->delete(); $this->clearRelatedCache($model); return $result; } public function deleteById(int $id): bool { $model = $this->model->findOrFail($id); return $this->delete($model); } public function deleteMultiple(array $ids): int { $deleted = $this->model->whereIn('id', $ids)->delete(); // Clear all cache since multiple records are deleted $this->getReadRepository()->clearCache(); return $deleted; } public function restore(Model $model): bool { $result = $model->restore(); $this->clearRelatedCache($model); return $result; } public function restoreById(int $id): bool { $model = $this->model->withTrashed()->findOrFail($id); return $this->restore($model); } public function forceDelete(Model $model): bool { $result = $model->forceDelete(); $this->clearRelatedCache($model); return $result; } public function forceDeleteById(int $id): bool { $model = $this->model->withTrashed()->findOrFail($id); return $this->forceDelete($model); } public function sync(Model $model, string $relation, array $ids, bool $detaching = true): array { $result = $model->{$relation}()->sync($ids, $detaching); $this->clearRelatedCache($model); return $result; } public function attach(Model $model, string $relation, array $ids, array $attributes = [], bool $touch = true): void { $model->{$relation}()->attach($ids, $attributes, $touch); $this->clearRelatedCache($model); } public function detach(Model $model, string $relation, ?array $ids = null, bool $touch = true): int { $result = $model->{$relation}()->detach($ids, $touch); $this->clearRelatedCache($model); return $result; } public function clearCache(): void { $this->getReadRepository()->clearCache(); } public function clearCacheForModel(Model $model): void { $this->clearRelatedCache($model); } public function clearCacheForCollection(Collection $models): void { $this->clearCollectionCache($models); } }