This is more of a non-code related question. I want your experience here and suggestion. I am designing this simple web application where I could just insert data, and then making sure the website will view that data based on categories.
In my controller, I have functions, each loading based on which category is selected from my main page.
Now I am wondering, is it better to create multiple controllers (like I used to have separate classes when using OO Php) for say CRUD operations, Listing the records, Search functionality, etc. Or just keep it all centralized in one controller (the current approach)? If multiple controllers, any recommendations?
You should have a controller for each separate functionality your websites provides.
For example:
controller for handling "regular" content (articles) (displaying articles, searching, rating, etc)
controller for handling user management (login, logout, registering, etc...)
controller for "static" pages like about, help, tos, etc...
And you should also handle all database operations in model classes, each for different entity (model for articles, model for users...)
I hope you got the point
Codeigniter uses an MVC structure, so you should actually use models for database operations, and separate them in a way that each model is used for a specific functionality.
If all the categories are handled the same way, you should add all the retrieving from db code in a single model, that way you simplify your code making it a lot easier to maintain.
Related
What we usually see in framework documentations are simple blog-like applications where each page is related to only one model and one controller.
How to deal with the most common case where a single page have to display information from different models?
Example:
A social network home page that shows:
Recent user posts
Recent users
News from the admins
Most played games
Is this supposed to be handled by a single controller that loads all this information from the different models and send it to a view that is potentially broken down into partials / elements?
Someone said in another question that I could create something like a HomePageController for pages like this. What if all that information should be displayed in the sidebar for all pages on the site, how do I handle that?
Typically, you'll collect all the different kinds of data and pass it to the view together:
MVC frameworks generally provide some way to map request URLs (e.g. /offers?id=5) to controllers (or their methods).
Let's assume that you want to display some data on your homepage.
To do this, you'll first define mapping from URL /home to some particular controller, let's say HomePageController.
Using your example data, you'll have something like this in your controller (in method that will handle request):
model.add(dao.getRecentUserPosts());
model.add(dao.getRecentUsers());
model.add(dao.getNewsFromAdmins());
model.add(dao.getMostPlayedGames());
render("viewName", model);
Upon request to some adress mapped to this specific controller, you will get different kinds of data from your Data Access Object (dao), and the add them to your model.
Once model is filled with data, you can pass it to a view ( = render view with this model), and in view you'll display it any way you want to.
I hope that basic flow is now clear to you.
Referring to #BeK's answer:
handling requests that take longer will always need an individual approach. You may choose to load this part asynchronously, you may (and probably will) try to cache as much as you can.
Loading the sidebar:
most of MVC frameworks provide some kind of 'base template' for your view.
That means you can define one part of view (e.g siderbar or footer) that is displayed on every page, and in particular controllers you only care about the dynamic parts. Those solutions are flexible enough to satisfy most of the typical needs.
There are a lot of options depending on what are you displaying in that sidebar - is it static or dynamic? what can be cached? etc.
There are several options here. It really depends on what kind of data you are loading. If one of the data requests takes a long time the view will not be displayed until all the data is gathered. If you break the view down in partials and let them load async, the user will have a better UX. In this way you can have the separate controllers/controller methods, complying with patterns like SRP.
If you want all the data to be displayed in the sidebar of every page, than maybe one controller taking care of it will be an easier solution, but again I would suggest take a look at the data you are loading and especially the time it takes to load all the data. Hope this answers your question or sets you on the right path.
alternate approach to follow SRP is using MVC child actions.
create many models and controller. each controller responsible for its own business logic
eg.
PostsController
NewsController
GamesController
HomeController
starting from HomeController that render the HomePage.cshtml
<div>#Html.Partial("Login.cshtml", Model.CurrentUser)</div>
<div>
<hgroup>
<h2>what's new</h2>
</hgroup>
<div>#Html.Action("WhatNew", "News")</div>
<div>#Html.Action("RecentlyPosted", "Posts")</div>
</div>
<aside>
<h2>Games</h2>
<div>#Html.Action("MostPlayed", "Games")</div>
</aside>
you may fetch list of many controller/actions name as string in HomeController then render multiple child actions in main page.
So I did some Google searching on the MVC pattern and I'm still not exactly sure what the "Model" part is. What exactly does it deal with? I'm rather new to programming so all the explanations I can find go right over my head. I'd really appreciate it if you could give me an explanation in simple terms.
Thanks
The simplest way I can describe it is to call it the "Data" part. If it has to deal with getting or saving data, it's in the model. If you have a web application, the model is usually where you interact with a database or a filesystem.
Model in MVC is a place where data presented by the UI is located. Therefore, it shouldn't be confused with Domain Model which serves as a skeleton that holds the business logic.
Certainly, for a small application that serves as a service for CRUD operations backed by a database these two models can be the same. In a real world application they should be cleanly separated.
Controller is the one who talks to the application services and the Domain Model. It receives updates back from application services updating the Model which is then rendered by the View.
View renders the state hold by the Model, interprets User's input and it redirects it to the Controller. Controller then decides if the Model is going to be updated immediately or first the information is forwarded to application services.
The Model can represent your "Domain Model" in smaller projects. The Domain Model consists of classes which represent the real-world entities of the problem you're dealing with.
In larger projects, the Domain Model should be separated out of the actual MVC application, and given it's own project/assembly. In these larger projects, reserve the "Model" (i.e. the "Models folder in the MVC project") for UI presentation objects (DTOs - Data Transfer Objects)
The model is respomnsible for managing the data in the application. This might include stuff like database queries and file IO.
the view is obviously the template, with controller being the business logic.
The model is used to represent the data you are working with. The controller controls the data flow and actions that can be taken with the data. The view(s) visualize the data and the actions that can be requested of the controller.
Simple example:
A car is a model, it has properties that represent a car (wheels, engine, etc).
The controller defines the actions that can be taken on the car: view, edit, create, or even actions like buy and sell.
The controller passes the data to a view which both displays the data and sometimes lets the user take action on that data. However, the requested action is actually handled by the controller.
I have a question concerning the structure of an MVC application. Suppose we have to realize a web-based application composed by several modules, such as shopping cart, store browser(end-user), store manager(admin) and so on.
It is of course possible to create one controller and use the routing to submit the requests to a specific controller's action method. However this would make the code quite messy and hinder the practice to vertically structure the application, namely to identify and distinguish which views, models and controllers are involved to fulfill a specific requirement (an example is given by Phil Haack).
Another approach is to use one controller for each application section, for instance one controller made available for end-user operations, another for the store administrator, another one for queries made by the shipping department and so on. The drawback to this approach is to have too many controllers that mess up your code, too dedicated for specific tasks and so difficult to reuse.
According to this two extreme situation, what is the best way to organize your controllers and routing policies? Do you use a structured approach or it depends on the type of application you are developing?
Thanks
Francesco
It is of course possible to create one controller and use the routing to submit the requests to a specific controller's action method. [...]
Another approach is to use one controller for each application section, [...]
You're overlooking a third alternative, which is the most common one. In general you should have one controller per resource. A resource is a model that is publicly exposed. In your specific storefront application, the resources would be things like Products, Orders, Customers, etc.
This is typically the proper level of abstraction, because controllers usually don't need to know about models other than the resources they touch. A controller that touches more than one resource should be viewed with some skepticism, since it's violating the single-responsibility principle.
You should try to follow REST as much as possible
Basically - that means controller for each 'collection' (Your entity).
If Your controllers will be RESTful, other parts (routing, views) will fit themselves accordingly.
I have lots of auto completes like City, country, companies, brands, people names, etc. Now my team is currently giving each autocomplete a separate model in codeigniter. The issue i have is then each autocomplete has its own code. I want to make it templatized so there is only 1 code base for all auto completes and it pulls the autocompletes in and out dynamic.
Is it possible or is the way my team is doing it the correct way?
Your CI models should be organized to reflect your domain, so in the case of cities, countries, companies and such, each are different entities and deserve a seperate model. More files does not mean it is less maintainable.
As for autosuggest, your model simply needs to deliver the data to a controller that will be called using Ajax. You can do the json_encoding of the data stream in the model or the controller, I prefer to use the controller.
So eventually yoiu hopefully have a single autosuggest plugin in the front-end that simply calls different controller URLs. These controllers know which model to use to get the autosuggest data.
This is a clean seperation of duties, and maintainable.
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.