0

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.

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?

Approach 1 - Nested Resource Controller

namespace App\Http\Controllers;

class SupplierContactController extends Controller
{
    public function all(Supplier $supplier)
    {
        return response($supplier->contacts);
    }

    public function store(Request $request, Supplier $supplier)
    {
        $supplier->contact($request->user()->id, $request->all());

        return response(null, 201);
    }
}

Approach 2 - Nested Resource Controller that extends another parent Resource controller

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);
    }
}

Approach 3 - Resource Controller with Methods for each Model Type

namespace App\Http\Controllers;

class ContactController extends Controller
{
    public function forSupplier(Supplier $supplier)
    {
        return $this->forModel($supplier);
    }

    public function forCustomer(Customer $customer)
    {
        return $this->forModel($customer);
    }

    public function storeForSupplier(StoreContact $request, Supplier $supplier)
    {
        return $this->store($request, $supplier);
    }

    public function storeForCustomer(StoreContact $request, Customer $customer)
    {
        return $this->store($request, $customer);
    }

    private function forModel(Model $model)
    {
        return response($model->contacts);
    }

    private function store(Request $request, Model $model)
    {
        $model->contact($request->user()->id, $request->all());

        return response(null, 201);
    }
}

Approach 4 - Resource Controller with Route Parameters and if statements

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->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->contact($request->user()->id, $request->all());

        return response(null, 201);
    }
}
SupaMonkey
  • 876
  • 2
  • 9
  • 25
  • I guess, the approach #2 with static calls might be hard to test. Approach #4 is hard-tight with routes. Not scaleable. – Tarasovych Aug 11 '18 at 21:49
  • By the way, dependency injection as in approach #1 seems good. If all your approaches make the same logic, the first one is the smallest and readable. – Tarasovych Aug 11 '18 at 21:51
  • The first one is what I have right now; but it seems like a waste. Its a separate resource controller per 'parent type' and a repetition of code. When I have 'contacts' that apply to many 'parent types', it feels wrong to repeat (essentially) the exact same code over and over. I also have other parent/child scenarios like this one which I would extend the same logic to. – SupaMonkey Aug 12 '18 at 06:23
  • Provide full code than, so we can refactor it or so. – Tarasovych Aug 12 '18 at 07:19
  • Sorry, but I dont think the 'full code' is required since this is a logic/best approach based question. There is a child (contacts) which can have many parents types (School, Supplier, Customer) - ie: a School can have a list of contacts; a Supplier can have its list of contacts, a Customer can have its list of Contacts - and so forth, and so forth. This logic can be brought to other 'types. eg: child = "banking details", once again School can have several banking details, supplier can have several banking details. The child details stay the same, there is a pivot table to link to the parent' – SupaMonkey Aug 12 '18 at 08:33

0 Answers0