Getting user input from Model Layer - model-view-controller

Have a problem following the MVP or MVC design pattern (applies to either one). I can't figure out how to cleanly prompt for user input from the model layer? Depending upon certain values in the model, I may need to prompt the user for input during the middle of a process.
For example, we'll take a hypothetical PO entry process. Say after the user hits a button in the view it calls the presenter passing in the PO details from the view. The presenter then calls the model to validate and insert the new PO into a collection of POs. One of the validation checks in the model is to make sure another PO has not already been entered with the same items. If one has, the app needs to prompt the user to confirm the PO is not a duplicate. The app is currently deep into the model. How do I go all the way back up to the view to retrieve the operator input, then return to the model code where it left off to finish the PO entry process?

In a paper I read on presenter first it was suggested that the presenter had dependencies on the model and on the view and subscribed to events from both the model and the view.
This would mean that you could raise an event from the model at the point where the processing cannot continue. The presenter would handle the event from the model by calling some method on the view (which would prompt the user). The return value from the method on the model would then be returned to the model (an in/out parameter to the event like the EventArguments subclasses used by .NET).

You might want to look at some form of notification interaction between your model and the other components of your UI pattern.
Martin Fowler wrote about it here.
As far as being deep in the model, getting user input, then going back into the model: don't. Your controller is responsible for modifications to your model, and should do the validation before attempting to change your model. This may require separating your validation from your update code.

Related

Is there a downside to validating data through a static method of the Model in an MVP setting?

I was recently reading about MVP, and at the end of the post the author starts to talk about Validation of Data. He mentions
I favour a single isValid() routine in the view.
...
An alternative approach, which is more in-line with the pattern, is to include this method in the interface and for the presenter to call this method (view.isValid()) before attempting to make changes to the model.
I don't think the validation should be handled in the View because it exposes more about the Model than the View should know, especially since we're trying to keep the View and the Model as separate as possible. Plus that method becomes redundant when you have multiple views referencing the same Model (e.g. a quick summary view vs. a more detailed view).
The Presenter has the most opportunity to validate the data, seeing as it is the bridge between the Model and View. I do like the "alternative approach", but I still don't like how it's using view.isValid. Plus I'm still not entirely sure if one presenter controls one view, or multiple view (a question for another time).
But one idea that did occur to me is to use a static isValid() method from the Model. You would call it in the Presenter, and the Presenter would pass all the relevant information from the View to the method. The method returns some form of valid or not-valid, maybe even specific enough to say which pieces of information aren't valid. To me this keeps all information relevant to the Model, within the Model, and accessible to Presenter, while keeping the View blissfully unaware of the Model.
Are there any shortcomings to this idea that other Validation practices solve, or is there any glaring downside to this method of Validation?

How should the MVC pattern work?

I have searched and searched but got no answers: How should the MVC pattern work?
So long I got two examples out of many similar ones: one of them suggests that the view should be updated by the controller, but the model is directly updated by the view, and another one suggests that the model should be updated by the controller, but the view should be updated by the model.
I have learned that the view should display content from the model fetched by the controller, and the model content would be altered by the view and updated by the controller.
It's been a year, and I got no answers. Maybe because the question is kinda opinion-based, or maybe because it didn't get much attention.
But ever since then I searched and studied more and more about best practices and design patterns, and now I feel confident enough to answer my own question.
Q: So, how should the MVC pattern work?
A: It should work the way you design it.
The MVC pattern defines three vital types of components: the Model, the View and the Controller:
The Model is what holds and manipulates the data you're working with: it handles persistence methods (writing/reading or CRUD) and has all the properties that your file/database table has;
The View is what displays the Model in a human readable way: it binds his visual components' values to properties of the Model;
Finally, the Controller is what notifies the View of changes on the Model, or notifies the Model of changes on the View: basically it's a sort of messenger, notifying two parts of each others' actions.
Now, how's the usual data flow of a MVC application?
The user changes a component value on the view;
The View queries the Controller about the value that the user passed;
The Controller then notifies the Model that it wants data about the value that the View passed;
The Model interacts with the database and gets the corresponding values (if they exist). After that, it notifies the Controller that it finished whatever it was doing;
The Controller notifies the View that the Model has been updated;
The View updates its' components accordingly, changing whatever values that may have changed.
That was only the reading flow, the writing flow is similar but a bit different:
The user changes values on the View;
The View sends those values to the Controller, saying that data changed and it should be persisted;
The Controller notifies the Model about the data changes, and passes the message along;
The Model then updates the database with the new/updated data, and notifies the Controller;
The Controller notifies the View that the Model has been updated;
The View displays a message to the user, saying that the operation was sucessful.
Now, when I first asked this question, I was with a Java-heavy mindset, so I wanted to know how would I go about implementing this in Java:
DAOs and Java Beans. You write the views and the controllers, but the models are split between data objects (Beans) and persistence objects (DAOs);
Java Beans with embedded persistence methods. You write the views, the controllers and the models. The models are Java Beans that have whichever persistence methods you need (the most basic ones being insert, select, list, update and delete).
So, my final answer is: There's a lot of correct ways of implementing the MVC pattern. But there's a series of guidelines you should follow if you want your implementation to be correct.

Where to put validation logic in MVC software architecture

I am actually starting to learn the mvc architecture.
I'm confused on whether to place my username registration validation logic in model or in controller.
I have some sort of status message that would tell the user whether the new username to register is available or not.
My confusion started because most sources say that it should be in the model because it involves the username data to validate before placing it on the database (rather than checking inputs to the username field). However, the status message should respond immediately prior to the change in the username field by user keypress or change, which lead me to think that it should be in the controller because it involves more on user events.
My concern is not actually on the framework to use but on the standard concept involving MVC. Where do I put the username validation logic based on the conditions/premise above?
As Shikhar says, the actual checking of whether the name is acceptable/available is a Model responsibility. The controller can provide an action that is called by some AJAX on the page, so that as each key is pressed, the text on the page is sent to the dedicated controller action which then validates it through the model (anything that touches the database is Model).
There are a couple of things to consider in the view, such as when the user is typing quickly, you should cancel the previous calls before making the new one as this can get confusing.
Also the controller post action that happens when the user submits the form at the end of their data entry should perform the same validation as the AJAX action did just to avoid race conditions between users.
It should be in the model as you have read yourself. I think you are getting confused between the "validation process" and "validation rules". Validation process will either be in controller on the client side but validation rules are properties of model.
As an addition to #Colin Desmond, a model-instance should never contain 'wrong' data and thus, in my opinion, in an MVC environment should contain validation logic. So that, regardless of the place where an instance of the model is created, it can never be initialized with wrong data and classes that operate on the model instance can rely on its data. The exception is if there is validation logic that is view dependent. View dependent logic (exceptions) should be implemented in the controller.
For example, validation of an email-address should be implemented in the model. However, a model might allow a bank transaction with a negative amount, but view A might not allow a transaction with a negative amount. The logic for this exception should be implemented on the controller.

MVC question: direct modell <-> view communication - why?

can anybody tell me, why communicates the model direct with the view in the MVC pattern, and why not just throught the controller?
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
Sometimes it is too costly to use Controller for simple View/Model communication.
If your view just shows raw data without any operation (filtration, visualization, modification ...) it is easy to forget about Controller.
But this behavior is so abuse-able sometimes it kills all of the advantages of MVC.
And this where MVP comes in:
MVP (Model-View-Presenter) cuts the connection between model and view and every thing pass through man-in-the-middle (Presenter).
The views know of the model and will interact with the model.
If a button is clicked an action message might be sent to a model object in order to get
something done.
If a new value is typed into an entry field an update message might be sent to a model
object in order to give it its new value.
If a value is needed for a display an enquiry message might be sent to a model object in
order to get a value.

CAkePHP calling one controller action from a different controller

In my app, I want to add a user notification each time a user receives a comment on an image or other page. Therefore in my add action in my images controller, I'd like to also call the addNotifications action which is in my Notifications controller. I'm trying to stay away from requestAction based on the warnings, but is there another way?
Workflow is this:
New event occurs -> trigger addition of notification in notifications table -> email user that notification exists.
If it's going to be a notification for all sorts of things, then I would consider something in the app_controller as this will make it available across your whole application. Meaning you'll be able to call something like
$this->Notify($user['User']['email'], 'MyNotifyType', 'MyTemplateName');
Then you can deal with the other bits in your app controllers notify function. You might need to add your User model to your app_controller, which could be tricky.
I would try using uses() as this could allow you to add the model and thus pull user data from your app_controller if you wanted to say include the users last login details, username or formal greeting etc. http://api.cakephp.org/class/controller
If you want to call a method that is based on another model, you need to place it in the model class, so in your example in the the Notification model. You can then call it from your Images controller with
$this->Image->Notification->add($params);
if the Models are associated. If they are not, you could either connect them on the fly or go with the previous proposal and add the function in the appController (which is not really perfect, because functions in the AppController should not depend on a certain model but be generic)

Resources