Complete code for DRY resource controllers in Laravel Below is the complete code which accompanies DRY resource controllers in Laravel. GenericResourceController <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Session; class GenericResourceController extends Controller { protected $request; protected $object; protected $id = false; // child class properties protected $model = ''; // e.g. 'App\Product' protected $fields = []; protected $intermediaries = []; // e.g. ['tags' => ['save' => false, 'destroy' => true]] protected $objectLang = ''; // e.g. 'product' protected $redirectAfter = [ 'store' => '', // e.g. 'products.show' 'update' => '', 'destroy' => '', ]; public function store(Request $request){ $this->request = $request; $this->processFormSubmission(); return $this->redirect('store'); } public function update(Request $request, $id){ $this->request = $request; $this->id = $id; $this->processFormSubmission(); return $this->redirect('update'); } public function destroy($id){ $this->id = $id; $this->destroyObject(); return $this->redirect('destroy'); } /** * Handle form submissions for new and existing records */ protected function processFormSubmission(){ $this->setObject(); $this->validateRequest(); $this->setObjectData(); $this->saveObject(); $this->handleIntermediaries('save'); $this->setSuccessMessage('save'); } /** * Handle destroy actions */ protected function destroyObject(){ $this->setObject(); $this->handleIntermediaries('destroy'); $this->deleteObject(); $this->setSuccessMessage('destroy'); } /** * Set the object property. * If there's no id, create a new object of the appropriate type, * otherwise instantiate the object to correspond to the object id. */ protected function setObject(){ $model = $this->model; if($this->id === false){ $this->object = new $model; } else { $this->object = $model::find($this->id); } } /** * Cycle through the form fields and validate them. */ protected function validateRequest(){ if( isset($this->fields['slug']) && $this->request->input('slug') != $this->object->slug ){ $this->fields['slug'] = 'required|alpha_dash|min:5|max:255|unique:' . $this->object->getTable() . ',slug'; } $this->validate($this->request, $this->fields); } /** * Cycle through the form fields and set them in the object. */ protected function setObjectData(){ foreach($this->fields as $field => $rules){ $this->object->$field = $this->request->$field; } } /** * Save the object to the database */ protected function saveObject(){ $this->object->save(); } /** * Delete the object from the database */ protected function deleteObject(){ $this->object->delete(); } /** * Sync many-to-many relationships */ protected function handleIntermediaries($action){ if(isset($this->intermediaries) && is_array($this->intermediaries)){ foreach($this->intermediaries as $intermediary => $isAllowed){ if($action == 'save' && $isAllowed['save']) { $this->syncIntermediary($intermediary); } elseif($action == 'destroy' && $isAllowed['destroy']){ $this->detachIntermediary($intermediary); } } } } /** * Sync intermediaries with the object */ protected function syncIntermediary($intermediary){ if( is_array($this->request->$intermediary) && count($this->request->$intermediary) > 0 ){ $idList = $this->request->$intermediary; } else { $idList = []; } $this->object->$intermediary()->sync($idList); } /** * Detach intermediaries from the object */ protected function detachIntermediary($intermediary){ $this->object->$intermediary()->detach(); } /** * Set a success message in the session */ protected function setSuccessMessage($messageType){ $messages = array( 'save' => 'The ' . $this->objectLang . ' was successfully saved.', 'destroy' => 'The ' . $this->objectLang . ' was successfully deleted.' ); Session::flash('success', $messages[$messageType]); } /** * Redirect to the next route */ protected function redirect($action){ $route = $this->redirectAfter[$action]; if(strpos($route, 'index') !== false){ return redirect()->route($route); } else { return redirect()->route($route, $this->id); } } } Sample child controller <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Session; use App\Product; // don't forget this! class ProductController extends GenericResourceController { protected $model = 'App\Product'; protected $fields = [ 'product_name' => 'required|max:255', 'description' => '', 'slug' => 'required|alpha_dash|min:5|max:255', 'price' => 'required|float', // etc... ]; protected $intermediaries = ['tags' => ['save' => true, 'destroy' => true]]; protected $objectLang = 'product'; protected $redirectAfter = [ 'store' => 'products.show', 'update' => 'products.show', 'destroy' => 'products.index', ]; public function index(){ } public function show(){ } public function create(){ } public function edit(){ } }