Search code examples
phplaravelcontroller

Laravel Calling Multiple Controllers from Form Submit


I want to submit a form, and once that submit button is pressed, I run a bit of code. During this 'bit of code', part of its job will be to create a student, and also create a lunch order. (information pulled from the form).

From what I've been reading, I should be aiming to use CRUD, which would mean I should have a Student Controller and a LunchOrderController.

I want to call the @store method in each controller.

If I was doing it the 'bad' way, the form would have [action="/students" method=POST]. And in that route, it would then call /lunchorder/ POST, and then return to a page (redirect('students')).

However, as above, I don't want to call a controller from a controller. Therefore, the initial [action="/students" method=POST] should be something else instead, and this new entity will then call the StudentController, then call the LunchOrderController, then redirect('students').

But, I don't know what this new entity is, or should be, or how to link to it.

It is just a new route to a new controller which is ok to call other controllers from? Or is there some other place I should be sending the form data to (maybe models?), to them call the controller? Or am I way off base and need to take some steps back?

I'm fairly new to Laravel but am wanting to use best practice as much as possible. All my reading of other posts don't seem to explain it enough to get my head around how its meant to work.

Edit: Some code to give an idea of what I'm getting at.

Student_edit.blade.php

  <form action="/student" method="POST">
    {{ csrf_field() }}

    <label>First Name</label><input name="firstname"  value="">
    <label>Last Name</label><input name="lastname"  value="">
    <label>Lunch Order</label>
    <select name="lunch_value" id="">
        <option value="1" >Meat Pie</option>
        <option value="2" >Sandwich</option>
        <option value="3" >Salad</option>
        <option value="4" >Pizza</option>
    </select>


    <input type="submit" value="Submit" class="btn btn-primary btn-lg">
</form>

web.php

Route::resource('/students', 'StudentController');
Route::resource('/lunchorder', 'LunchOrderController');

Studentcontroller

public function store(Request $request)
{
    Student::create(request(['firstname', 'lastname']));

    LunchOrderController::store($request, $student_id); //<- This isn't the correct syntax

    return redirect('/students');  

}

LunchOrderController

public function store(Request $request, $student_id)
    {

        LunchOrder::create(array_merge(request(['lunch_value']), ['student_id' => $student_id]));

        return null;  

    }

Solution

  • Personally I would create a 'Logic' Directory as: app/Logic. Some people prefer Repositories etc, but this is my preference. For your specific requirement I'd create the following file:

    app/Logic/StudentLogic.php

    StudentLogic

    <?php
    
    namespace App\Logic\StudentLogic;
    
    use App\Student;
    use App\LunchOrder;
    
    class StudentLogic
    {
        public function handleStudentLunch(Request $request): bool
        {
            $student = Student::create(request(['firstname', 'lastname']));
    
            if(is_null($student)) {
                return false;
            }
            
            LunchOrder::create(array_merge(request(['lunch_value']), ['student_id' => $student->id]));
    
            return true;
        }
    }
    
    

    StudentController

    public function store(Request $request)
    {
        $logic = new StudentLogic();
    
        $valid = $logic->handleStudentLunch($request);
        if($valid) {
            return redirect('/students');  
        }
        abort(404, 'Student Not Found');
    
    }
    

    ASSUMPTIONS

    Student is stored under App/Student & LunchOrder is stored under App\LunchOrder You will also need to use App\Logic\StudentLogic in StudentController

    The reason I'd split this out into a Logic file is because I do not like 'heavy' controllers. Also, I'm not entirely sure what you're trying to acomplish here, but creating a student on the same request you create a LunchOrder seems like you're asking for trouble