CrastyCrap's avatar

Model or Controller

I have a question each time I follow a video on Youtube or Laracast etc i found the dev in the video add system logic in controller, but from my side i am using the model and calling it in my controller as example if i want to register new user i add all the logic in model and call this function in controller and pass my request in it and i am doing that concept to prevent any duplication codes , i am just wanted to know what is better using model or controller to write application logic

0 likes
11 replies
LaryAI's avatar
Level 58

Both models and controllers have their own responsibilities in the MVC architecture.

Models are responsible for handling data and business logic. They represent the data and the rules that govern how that data can be manipulated.

Controllers, on the other hand, are responsible for handling user input and coordinating the flow of data between the model and the view. They are the glue that binds the model and the view together.

In general, it is a good practice to keep the business logic in the model and keep the controller as thin as possible. This makes the code more modular and easier to maintain.

However, there may be cases where it makes sense to put some application logic in the controller. For example, if the logic is specific to a particular use case and does not belong in the model.

In the case of registering a new user, it would make sense to put the business logic in the model. Here's an example of how you could implement this:

// User model
class User extends Model
{
    protected $fillable = ['name', 'email', 'password'];

    public function register(array $data)
    {
        $user = $this->create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);

        // Send welcome email
        Mail::to($user->email)->send(new WelcomeEmail($user));

        return $user;
    }
}

// UserController
class UserController extends Controller
{
    public function store(Request $request)
    {
        $data = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8|confirmed',
        ]);

        $user = new User;
        $user->register($data);

        return redirect('/home');
    }
}

In this example, the register method is defined in the User model and handles the business logic of creating a new user and sending a welcome email. The store method in the UserController simply validates the request data and calls the register method on the User model.

christian-qode's avatar

You should avoid using code multiple times, so if you do in a controller and API resource for example, store it in the model.

In the example above, I'd prefer to create Model instances in the controller, because the mapping from data to attributes may differ in different situations.

1 like
CrastyCrap's avatar

@christian-qode That's what I am saying but I am keeping see some Devs add all logic with validations in the controller and their models is empty and they never use form requests so i wondered why they are doing this or maybe something missing me

egarcia's avatar

From my point of view and based in my experience, If the logic implies updating only records in the database or with related models is fine putting that on the model (indeed you can implement a repository pattern where the repository has methods that are related to other models and the model only for transactions from the model itself) and call those methods in the controller.

In the other hand if the logic implies more than only database transactions is fine to put that in the controller, for example if the logic needs to process form request, read from the database, update a model, send notifications (email, database, etc.) put that on the controller, so the controller works like a glue between different components.

That way you can test, maintain and update your code from different approaches keeping a balance between fat models or fat controllers.

CrastyCrap's avatar

@egarcia my main point is the reusability I mean in controller functions we return to view or JSON (in API) so if I found that I need this logic again I will have to rewrite it again as an example if I need to register a new user and I need to allow user register in different places like user can be invited or he can register an account so I have to write the logic of user registration twice but if I put that logic in model or service I can call the function as many i

egarcia's avatar

@CrastyCrap yeah, you are right, also you can use Events, if the logic takes a couple of steps to be completed (listeners) this is just another approach

1 like
veinhugain's avatar

Actions are the next cool thing. I prefer the stepping stone on the way there of a service. let the Model know of itself and its relations. and maybe a few derived values like FullName from first and last.

But Have services that do the logic. Let the controller validate the request gather some other initial data like the user involved and pass the validated request data and user to a service Receive back and Option (false | ValidAnswer) return yourview/json

CrastyCrap's avatar

@veinhugain I don't understand what are the actions can u talk more about it or add link ? the next point yea services will do the job but I kinda prefer using models to be able to use laravel service container and create instance form model instead from dial it in services but overall it will do the job and prevent code dublication

martinbean's avatar

@CrastyCrap “Actions” are just a term Spatie coined for something that existed for decades beforehand (commands). They’re essentially a single class that encapsulates a single piece of business logic. So the idea is, your models represent “things”, but then you have action classes that do stuff with your models.

Personally, I’ve found Laravel projects remain maintainable and easy to reason about if you stick to conventions. So I use resourceful controllers (controllers with a subset of index, create, store, show, edit, update and destroy actions), validation in form request classes; and authorisation in policy classes. If there’s a gnarly bit of business logic, or something that is used in multiple places, then I’ll extract that common logic to its own class, where I can re-use it. This is handy for say, things you want to do in a controller but also in an Artisan command.

3 likes

Please or to participate in this conversation.