I have a model that I require to update, such as User. In a large application, this User will also have relationships, and updating it would be more than a mere User::find($id)->update(Input::all()).
Should the updating be performed in the Controller, or be a method within the User model itself?
I always thought that I should put it in the model, since it is model specific. But I've seen most people perform the task in the controller. What is the reasoning for this?
As said in the pattern names, the controllers control any model query or update. Based on this, the controller will be responsible for fetching, changing and saving the model.
If some actions are to be reused in many controllers, acting on a set of models, they would go in a "repository".
In your example, you are using Input::all() to hydrate your model, which you definitely have to change. Any user value has to be checked and/or sanitized. I would also recommend against using all and prefer either get or post, so you set up a minimal restriction.
So, I definitely let the controller be responsible for the "glue", having repositories for any collection matter, services and hydrators to change the object, and the model itself staying for only getters and setters, managing their own data in their own scope.
Related
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.
I'm really confused by this... still.
I asked a similar question to this a while before, but i'll ask it even simpler now.
I see this in a lot of samples and tutorials. How could you put [Bind(Exclude="ID")] on an entire Model, and expect to do Edits on the model? If you get pack all the properties of a model on a POST but not the ID, then how do you know which ID to edit?
Even if i'm using ViewModels... i'm probably creating them without IDs. So in that case... also... how do I know which ID was updated on an Edit?
Yes, i understand that there is a "security" element to this. People can hijack the ID... so we need to keep people from updating the value during a POST. But... what is the correct way to handle edits then? What's common practice?
I feel like i'm missing something VERY trivial.
In MVC requests are processed by the model binder when the client makes a request. If you include models on your controllers then, as far as I'm aware, you actually have to specify the model you wish to bind to by prefixing your arguments with the model name (unless you only have one argument which is the model)
SomeModel_ID
Now, in some cases you might want to exclude certain properties from being bound to because they pose a security risk, which you seem to be happy with as a concept. We will exclude ID on the model, preventing any client request from posting this value in plain text.
Now why might we exclude an entire model? Well not all controller arguments are pre-processed by a model binder. RedirectToAction for example does not pass through the model binder, so it is conceivable in this instance for you to create a new model in a POST controller action, and redirect to a GET controller action, passing along a sanitised model. That model cannot be populated by the client, but we are free to populate it ourselves on the server side.
The only time I bind to a model is when I have a view model and an associated editor for that model. This makes it really easy to inject a common editor into a page and to encapsulate those properties. If you have to exclude certain properties from being bound to I would argue that you are doing it wrong.
Update
Following your comments I think I can see why you might be confused. The model bind excluder prevents the client from ever setting a model property. If you need this property to do your updating then you simply can't exclude it. What this does mean then is that the user could potentially post back any ID. In this case you should check that the user has permission to be modifying any objects or database records associated with this ID before serving the requested update. Validating the arguments is a manual process. You can use data annotations for validating inputs, but this isn't likely to help very much with access permissions. It's something you should be checking for manually at some stage.
You know the ID because it's passed to you through the page address. So:
http://yoursite.com/admin/users/edit/20
Will populate your ID parameter with 20. If it's used in a POST (ie, the information is filled in), just manually fill in the ID field and pass it to the database controller in whatever manner you have devised.
This is also immune to (trivial) hijacks because if they were to write some other ID besides 20, they wouldn't be updating the user with ID 20 now would they? :)
Suppose, as part of an iphone application, I need to show user a list of some of some objects.
The model
Represents actual objects to be shown
Brainless data, collection of getters and setters
The view
Displays the list, passes received actions to a controller
Presentation layer
The Controller
Interprets actions received from the view and takes actions on data
Sits between the view and data
In this picture, would be be controller's responsibility to persist model to disk, or, should it be a part of Model's logic? Request to do this will come from a controller, but, should the controller know how to save data to disk, or should data know how to save itself to disk?
This is wrong.
Model is responsible for all the business logic. Additionally model is not directly aware of database or any other data storage medium. When model is initialized it receives factory for creating DAOs or DataMappers which are the ones responsible for storing and retrieving the informations.
Controller interprets the received information from view , and changes the state of model and view.
View either receives information from a persistent model via observer pattern ( classical MVC ) or request data from models ( Model2 MVC ).
I can see this going both ways. I would think that this logic goes into the model this way the controller is a little cleaner. Also, if you're using this functionality across models and it's mostly consistent e.g $person->saveData(), $user->saveData() then you could possible extend the base model so it would be inherited by other models and save you from duplicate code.
If this logic is incorporated into the model it would probably be a good idea to make it flexible enough so that the controller can override the persisting of data. So maybe, pass an argument into the model function $person->save( false ) This false would prevent the model from persisting the data but on default would be true.
I am quite new to MVC. I am having the following questions, please help me clarify those questions, thanks a lot.
Q1. Where should I populate my view model? e.g. My view model is very big, and contains a lot of the dropdown listbox, multi select list and the other few complex objects. I am currently populate them inside the view model self, by passing the model through the constructor, and load all the object data within the constructor. I also see my college populate the viewmodel inside controller. so I am confusing now, coz lots of people suggest to keep the controller small and skinny.
Q2. We are using the linq2sql as data access layer, should I use the table entity in my viewmodel instead of creating separate model class? Expert said it's bad, but if create seperate model class, I basically repeat them and I also need to copy those value to linq 2sql entity every time when I want to persist data, it's not that fun, too much work.
lots of people suggest to keep the controller small and skinny.
Yes. What people mean is that the controller should not contain any logic, except for model <-> view mapping. With model I mean the "M" in MVC.
Q2. We are using the linq2sql as data access layer, should I use the table entity in my viewmodel instead of creating separate model class? Expert said it's bad, but if create seperate model class, I basically repeat them and I also need to copy those value to linq 2sql entity every time when I want to persist data, it's not that fun, too much work.
No. You should not. Read my answer here: ASP.NET MVC Where to put custom validation attributes
Use a mapping framework for the model -> viewmodel conversion.
Update:
From what I understand, you suggest to assembly the viewmodel inside the controller (I mean call the business layer or repository to get my data) and use controller to call the business logic dealing with the data, am I right?
yes. The controller is really a glue between your business layer / repositories and your views. The views (and view models) should know nothing about them and the business layer / repositories should know nothing about the controller/view.
The controller was created for just that purpose. To create an abstraction between the user interface layer and the lower layers. Hence the only code that should exist in the controller is to make that possible (and therefore following the Single Responsibility Principle)
If you start adding that logic into your view models you start to add coupling between the lower layers and the user interface layer. Doing any changes in the lower layers will therefore also affect all your view models (instead of just the controller
your viewmodel should be a poco, and should most certainly not be handling the mapping of the model. if you don't want to map your model to your viewmodel in the controller i would suggest you look at something like automapper. it makes it easy.
once you've mapped from your model to your viewmodel, any extra properties that need to be set such as your lists should be set in the controller.
as i stated previously, definitely don't tie your viewmodel to your current orm or table structure. you never know what might need to be refactored, and if you can handle it via an automapper mapping instead of changing your view and viewmodel then you've saved yourself a significant amount of time.
Hey guys - here's a question on Zend Framework or better on MVC in general:
I am asking myself for a quiet a long time now, if it is a good idea to push business objects (User, Team, etc.) to my views or if it would be better just to push dump data containers such as arrays to the view for rendering.
When pushing business objects to my view I have a much tighter coupling between the views and my domain model, however, the view could easily do things like foreach($this->team->getUsers() as $user) { ... } which I personally find very handy.
Providing domain model data in dumb arrays to me looks more robust and flexbile but with the costs of that the view cannot operate on real objects and therefore cannot access related data using object's method.
How do you guys handle that?
Thanks much,
Michael
It's better to make your View access a Domain Model object in an object-oriented manner, instead of using the Controller to convert Model data into plain scalars and arrays.
This helps to keep the Controller from growing too fat. See the Anemic Domain Model anti-pattern. The Controller only needs to know what Model to instantiate, passes the request inputs to that Model, and then injects the Model into the View script and renders. Keep in mind that a Domain Model is not a data-access class.
You can also write View Helpers to encapsulate a generic rendering of a Domain Model object, so you can re-use it in multiple View scripts.
Your View should accesses the Domain Model only in a read-only manner. View scripts should not try to effect changes to the Domain Model.
You can also design your Domain Model to implement ArrayObject or other SPL type(s), as needed to make OO usage easy in the View script.
It's true, a large driving motivation of MVC and OO design in general is decoupling. We want to allow each layer to remain unchanged as the other layer(s) are modified. Only through their public APIs do the layers interact.
The ViewModel is one solution to abstract the Model so that the View doesn't need to change. The one I tend to use is Domain Model, which abstracts the details of table design, etc. and supplies an API that is more focused on the business rather than the data access. So if your underlying tables change, the View doesn't have to know about it.
I would expect that if there's a change to the Domain Model, for instance it needs to supply a new type of attribute, then it's likely that your View is changing anyway, to show that new attribute in the UI.
Which technique you choose to decouple one layer from the others depends on what types of changes you expect to be most frequent, and whether these changes will be truly independent changes, or if they will require changes to multiple layers anyway.
The "standard" approach would be to completely prepare the model in the controller (e.g. fetch all teams, including users) and then send that to the View for presentation, but you are not bound by that. The data structures can be whatever you want it to be: Array, ArrayObject or custom Classes - anything you deem appropriate.
I dont use Zend framework, so this is in repsonse to the general MVC Have a look at the ViewModel pattern.
http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx
I'm comming from a .Net MVC point of view but I believe the concepts will the same.
I will do all my view rendering in the controller bascially like below
model only output dataset/objects (this should contain the most code)
controller assign view and add necessary HTML and make use of models
view only contains placeholder and other presentation stuff and maybe ajax call
So my team can work on each part without interrupting each other, this also add some information security to the project i.e no one can retrieve all the working code they only communicate by variables/object spec.