title: Nested Resource - Controller - Best Approach?
body: <p>I am currently building an application where I have several Models that have the ability to 'have contacts' and wondered how to handle that in the best way in the controllers.</p>
  
  <p>I have laid out some approaches below - which one do you guys think is the best and why or the one you personally use and why?</p>
  
  <p><strong>Approach 1 - Nested Resource Controller</strong></p>
  
  <pre><code>namespace App\Http\Controllers;
  
  class SupplierContactController extends Controller
  {
      public function all(Supplier $supplier)
      {
          return response($supplier-&gt;contacts);
      }
  
      public function store(Request $request, Supplier $supplier)
      {
          $supplier-&gt;contact($request-&gt;user()-&gt;id, $request-&gt;all());
  
          return response(null, 201);
      }
  }
  </code></pre>
  
  <p><strong>Approach 2 - Nested Resource Controller that extends another parent Resource controller</strong></p>
  
  <pre><code>namespace App\Http\Controllers;
  
  class SupplierContactController extends ContactController
  {
      public function all(Supplier $supplier)
      {
          return parent::all($supplier);
      }
  
      public function store(Request $request, Supplier $supplier)
      {
          return parent::store($request, $supplier);
      }
  }
  </code></pre>
  
  <p><strong>Approach 3 - Resource Controller with Methods for each Model Type</strong></p>
  
  <pre><code>namespace App\Http\Controllers;
  
  class ContactController extends Controller
  {
      public function forSupplier(Supplier $supplier)
      {
          return $this-&gt;forModel($supplier);
      }
  
      public function forCustomer(Customer $customer)
      {
          return $this-&gt;forModel($customer);
      }
  
      public function storeForSupplier(StoreContact $request, Supplier $supplier)
      {
          return $this-&gt;store($request, $supplier);
      }
  
      public function storeForCustomer(StoreContact $request, Customer $customer)
      {
          return $this-&gt;store($request, $customer);
      }
  
      private function forModel(Model $model)
      {
          return response($model-&gt;contacts);
      }
  
      private function store(Request $request, Model $model)
      {
          $model-&gt;contact($request-&gt;user()-&gt;id, $request-&gt;all());
  
          return response(null, 201);
      }
  }
  </code></pre>
  
  <p><strong>Approach 4 - Resource Controller with Route Parameters and if statements</strong></p>
  
  <pre><code>namespace App\Http\Controllers;
  
  class ContactController extends Controller
  {
      public function all(string $type, int $id)
      {
          if ($type === 'supplier') $model = Supplier::find($id);
          if ($type === 'customer') $model = Customer::find($id);
  
          return response($model-&gt;contacts);
      }
  
      public function store(Request $request, string $type, int $id)
      {
          if ($type === 'supplier') $model = Supplier::find($id);
          if ($type === 'customer') $model = Customer::find($id);
  
          $model-&gt;contact($request-&gt;user()-&gt;id, $request-&gt;all());
  
          return response(null, 201);
      }
  }
  </code></pre>