Why in Laravel out of the box is validation implied in the controller, and not in the model?

The documentation states that the Base App\Http\Controllers\Controller includes a treit ValidatesRequests , which already contains methods for validation.

The question is why does not the base class of the model immediately contain validation methods?

After all, so much has been said about thin controllers of thick models. For example, the answer from @HaruAtari from Toaster:

I think that the “fat model, thin controller” is the most suitable option. All application logic must be contained in models. A model is not just entities from a database, it is also an encapsulated processing logic. And the controller should tell the model what to do and render the views.

For example, this piece of code is wrong:

 class MyController { public function myAction() { $user = new User(); $user->load($_POST); if ($user->valiadate()) { $user->saveToDatabase(); } else { throw new Exception("..."); } } } 

Wrong because the controller knows how the model saves data. That at first there is a validation, and then preservation in. And if you then decide not to carry out a validation, or add another checking method (for example), then you will have to do it everywhere.

Correctly, this is how: in the model, define a method containing logic:

 class User { public static function create(array $data) { $record= new static; $record->load($data); if($record->validate()){ $record->saveToDatabase(); } else { throw new Exception("..."); } return $record; } } 

And in the controller just pull it and transfer data there:

 class MyController { public function myAction() { $user = User::create($_POST); } } 

Thus, all the logic of the model (including validation) is encapsulated inside the class, and other classes do not know how this happens.

This approach makes it easier to maintain the code and also makes writing tests easier.

  • one
    Not familiar with Laravel, but the model is the semantic core of the application. Therefore, there is such a position (I do not approve and do not blame) that validation should be put into controllers, and the reverse process (formatting, for example, in the form of JSON) into templates. That is, the model works a priori only with the correct input data and provides only data in a form that does not depend on how they are displayed further. On the other hand, they say that the "valid" ID from the query may not be in the database table at all, that is, it is not valid. And only a model can handle this situation. - user239133
  • Imagine you have a controller, for example, store and update methods. You will have to transfer the Request object to the model and in case of an error the model will return an array of errors. Can I still do a redirect from the model? Then why the controller? - Jonny Manowar
  • Jonny is not exactly like that. Then why the controller? The controller is just needed for processing and preparing the Request object, in our case. To pass parameters to the model and to return the view. Everything. In the model, we must not pass an Request object, but an array, for example, $ data = $ request-> all () or, for example, $ data = $ request-> except ('_ token'); - prepared version. In case of validation errors, it is not necessary to transfer an array of errors, it is enough just to stop the script in the model and transfer control to the controller, and return the view, without an array of errors. The $ errors array will be available and will store errors. - serba

1 answer 1

Specifically, in Laravel, the model is an entity, for example, a table from the database, validation refers to business logic and is passed to the controller, respectively.