ViewModels
A Yuga ViewModel is a special class that represents the data model used in a specific view.
What is a ViewModel?, What makes it different from a controller?
In a yuga
application, every view has a code behind file
which in this case is our view model, View models
can work as controllers
but the main difference lies in how they couple with views, a controller
can return any view and it doesn't interact with the view itself while a view model
interacts directly with the view and returns only that view. In fact, you don't tell it the view it has to return, It already knows it.
A view model in a yuga application binds a form to a real database model
such that the developer doesn't need to do the mapping of form fields to a model them selves.
It has automatic validation
of form fields. This can turn out to be a time saver, if custom validation is needed, a validate
method is provided to a model to which the view model is bound and the view model will run that method instead of the default.
While you can do pretty much everything from within a controller, a view model simplifies your work by taking away tasks like
validation
andform-model
binding.
Basic ViewModels
Defining ViewModels
Below is an example of a basic ViewModel class. Note that the ViewModel extends the base ViewModel class that comes with Yuga. The base class provides a few convenience methods such as the onPost, onLoad, onGet
methods, which can be used whenever those events occur.
What's in the App class that the above class is extending? Let's find out
The route that corresponds to this UserViewModel
is as below:
Constructor Injection
The Yuga service container is used to resolve all Yuga ViewModels. As a result, you are able to type-hint any dependencies your ViewModel may need in its constructor. The declared dependencies will automatically be resolved and injected into the ViewModel instance:
Creating ViewModels using yuga console command
ViewModels can be created using the php yuga make:viewmodel
command
i.e php yuga make:viewmodel UserViewModel
would produce the following scaffold:
Model binding to the ViewModel
Think of this as an easier way of mapping every form value to an appropriate Object attribute or property. In yuga
, this works like magic.
When a form is submitted, the ViewModel
looks for the bound Model from the scope and maps every form field to a property on that Model
and finally tries to run a validator
to every field on the form to make sure that every form field is not empty for starters.
The default bound model is \Yuga\Models\ElegantModel::class
But of course the table that is bound to this model is elegant_models
which basically doesn't make any sense for every form, so how do we bind a model to a form, Well, there're two ways of doing this,
You may skip binding to the form yourself and instead set a table to be bound to the
ElegantModel
class, this is done as below:$this->setTable("my_table");
inside of the view-model's constructor.Or you can bind any other model you would like to use instead of
ElegantModel
as below:
Basic Structure
When a form is submitted and it is a post request method, the onPost
method is run and so this is where your code for form manipulation should reside.
Example of a view (My.php
)
The code behind to the above view is below: (MyViewModel.php
)
The route corresponding to the above ViewModel
could be any route but Let’s say that it's:
The model
parameter in the onPost
method in the MyViewModel
ViewModel
, is the bound model to the form inside the My.php
html file. It can only be an instance of Yuga\Database\Elegant\Model
for it to work well with the ViewModel
.
By default, the bound model is Yuga\Models\ElegantModel
Like the code above, you just have to call the save method to the model since it’s an instance of Yuga\Database\Elegant\Model
, When the save method is called, It will try to insert
or update
the database table depending on the bound model
Form Validation
Forms in view-models are validated automatically for required field validations. This means, if a form is submitted to the server, the framework will look for the form, validate it (making sure every field has a value basically) then bind it to the appropriate model, then provide it as an Argument to the onPost
method as below:
You can just call the save
method on the $model
variable since $model
is already a valid Elegant Model.
Sometimes you want to customize how the validation is done, well, yuga has your back already, you just have to do the following in your model
If the above model is the one bound to the form, yuga will run its validate
method instead of the default. Be warned though, when you run a custom validation, you will have to do it for every form field not just on the one field you want to customize.
Last updated