*/ abstract protected function modelClass(): string; /** * Map of request file field => ['column' => db column, 'folder' => storage folder, 'rules' => validation]. */ abstract protected function fileFields(): array; public function index(Request $request) { $query = ($this->modelClass())::query(); if (!$request->boolean('include_inactive')) { $query->where('is_active', true); } return response()->json($query->orderBy('order')->get()); } public function show($id) { return response()->json(($this->modelClass())::findOrFail($id)); } public function store(Request $request) { $data = $request->validate(array_merge([ 'name' => 'required|string|max:255', 'order' => 'nullable|integer', 'is_active' => 'nullable|boolean', ], $this->fileRules())); $attributes = [ 'name' => $data['name'], 'order' => $data['order'] ?? 0, 'is_active' => $data['is_active'] ?? true, ]; foreach ($this->fileFields() as $field => $config) { $attributes[$config['column']] = $request->hasFile($field) ? $request->file($field)->store($config['folder'], 'public') : null; } $item = ($this->modelClass())::create($attributes); return response()->json(['message' => 'Created successfully', 'item' => $item], 201); } public function update(Request $request, $id) { $item = ($this->modelClass())::findOrFail($id); $data = $request->validate(array_merge([ 'name' => 'sometimes|string|max:255', 'order' => 'nullable|integer', 'is_active' => 'nullable|boolean', ], $this->fileRules())); foreach (['name', 'order', 'is_active'] as $field) { if ($request->has($field)) { $item->$field = $data[$field]; } } foreach ($this->fileFields() as $field => $config) { if ($request->hasFile($field)) { if ($item->{$config['column']}) { Storage::disk('public')->delete($item->{$config['column']}); } $item->{$config['column']} = $request->file($field)->store($config['folder'], 'public'); } } $item->save(); return response()->json(['message' => 'Updated successfully', 'item' => $item]); } public function destroy($id) { $item = ($this->modelClass())::findOrFail($id); foreach ($this->fileFields() as $config) { if ($item->{$config['column']}) { Storage::disk('public')->delete($item->{$config['column']}); } } $item->delete(); return response()->json(['message' => 'Deleted successfully']); } private function fileRules(): array { $rules = []; foreach ($this->fileFields() as $field => $config) { $rules[$field] = $config['rules']; } return $rules; } }