Is there a general rule of thumb to how controllers should be organised?
Should Controllers only be created if they are linked to a domain model?
For instance if I have a 'Product' model, I would have a ProductController, which would have actions such as 'GetProductDetails' etc...
But what about things that don't have an actual model, such as searching for products, and returning multiple products on a page?
Since the Product model is the underlying model for all these interactions, should this functionality be included into the ProductController and have actions for searching and displaying multiple products, or should another be created for Search?
If you follow the pattern used by the scaffolding used in visual studio then yes you end up with one controller per entity so a product controller would have a actions that returned a list, a single product and an action for posting update to. In addition you might have additional search actions and any other product related actions. Which is just state and reinforce infer-on's answer.
However the reason why you would do this is that it means your code is easier to maintain - if you're looking for code to do with products you have one controller class to look in. You're also adhering to the principle of separation of concerns each controller is only concerned with one type of entity.
Further to this if your app grows much larger and you use an IoC / dependency injection pattern then you only need to inject one repository or business service per controller that is a search controller that offers methods to search for products and customers would need services or repositories for customer and products but a request might only be a customer search so the creation of the products repository was pointless hence you get inefficient and overly complex code. There are patterns to solve this issue but they involve even more code so to avoid this and to keep it simple stick to one root entity one controller.
You should manage every action which involve same resource with same controller, and you should implement that solution in accord with Richardson Maturity Model
A model (developed by Leonard Richardson) that breaks down the
principal elements of a REST approach into three steps. These
introduce resources, http verbs, and hypermedia controls.
so your API will be something like this:
/api/products GET Gets full list of all categories
/api/products/123 GET Gets the details for a single category
/api/products PUT Replaces the entire list of categories with
the one given
/api/products/123 PUT Update the specified category
/api/products POST Creates a new category
/api/products DELETE Deletes all categories
/api/products/123 DELETE Deletes the specified category
Related
I know its a question which has been asked hundreds of times before but I'm stressing over the naming scheme I adopt for Controllers in my ASP.Net MVC application.
Say, for example, I have a model called User of which I have the singular ability to view, update and delete. Likewise, I also have a collection of Users which I can search upon giving many results.
As the routing is of the form of {controller}/{action}/{parameter} then my 'English' head thinks that a URL of:
http://localhost/users/view/123 is not correct as the URL relates to a single product whereas:
http://localhost/user/view/123 is correct, as the user is viewing a single product
And likewise, with Product and Products:
http://localhost/product/edit/P123456
http://localhost/products/?searchQuery
This seems to make more sense (well, to me anyway) and thus means that I have to implement two Controllers for each Model but at least this means I know that the singular controller deals with a single entity whereas the plural version deals with multiple entities:
UserController -> Add, Edit, View, Delete
UsersController -> Find, Delete
I guess the only fly in the ointment is when I come across an entity which is the same singularly as plural but within the scope of my project, this could be quite a rare thing.
I'm sorry if this is mindless babble however I'd appreciate some input from users who've gone through this before.
It does not matter. Users are normally not navigation through your site by typing urls, but by clicking links, buttons, menu's, ....
Let's say I have a controller called Books (and a corresponding Book model), and a controller called Users (and a corresponding User model). Each of these controllers has the standard CRUD actions, and they serve as the vehicle for my website's API as well.
Most of the pages on my site fit into this framework easily. For example, viewing a book. Or viewing your user account. Or editing your user account. Etc.
But let's say I have an index that will be somewhat unique: I want to show a list of users AND a list of books. This raises a few questions:
What controller should this go under: UsersController, BooksController, or a new controller?
If I create a new controller, is that considered a violation of any MVC principles since it won't be tied to any particular model in particular?
How would this new controller action retrieve the data? If I write new ActiveRecord queries inside if it, them I'm repeating myself, since I already have code like this in my other controllers. I'd also prefer to consume my own API, if possible.
You can use scopes(google search it) in your model to keep your controllers lean. Depending on what you want to show you can create a new method and view. lets say you have a user dashboard that list your books and the authors which are in seperate models.
you can create a new method called def dashboard inside your user controller since it relates to your user.
def dashboard
end
you would create a helper method in your model to scope the specific queries. Remember to also add the proper route to your routes file.
I hope this helps
Whichever you want.
1) I would probably write another controller, though it may end up to be a question of taste and it may change with the context of the application.
2) I would fetch the data from both models. There is no MVC rule mapping controllers and models one to one.
I am not quite sure what you mean by "queries" but you can put them in model methods (or scopes) to avoid DRY. Of course one gets tempted to do simple queries in controllers because ActiveRecord encaplulates them as methods (e.g. User.find(n) )
I have read online that it is bad practice to use a "kitchen sink" model:
Rule #3 – The View dictates the design of the ViewModel. Only what is
required to render a View is passed in with the ViewModel.
If a Customer object has fifty properties, but one component only
shows their name, then we create a custom ViewModel type with only
those two properties.
Jimmy Bogard's subsequent explanation of how this is good, however, left me a little questioning. It'd be so easy to have my Model just contain a list of Customers, I could even use my POCO's.
So now I get to create custom little view model fragments for every page on the site? Every page that uses a Customer property would get one, but of course could not be shared since some of the information is extraneous, if one page used Age but not Name, for example. Two new mini view model classes right?
This is very time consuming, and seems like it'll lead to a million little custom view models - can someone elaborate as to the utility of this approach and why the easier approach is bad?
View model class can be used not only to transfer values, but it also defines data types (data annotations), validation rules and relations different then ones used in model. Some advantages that come to my mind right now:
There are different validation rules when you change user's password,
change his basic data or his subscription setting. It can be
complicated to define all these rules in one model class. It looks
much better and cleaner when different view models are used.
Using view model can also give you performance advantages. If you
want to display user list, you can define view model with id and name
only and use index to retrieve it from database. If you retrieved
whole objects and pass it to view, you transfer more data from
database than you need to.
You can define display, and editor templates for view models and reuse them on different pages using html helpers. It looks much worse, when you define templates for model POCOs.
If you would use your POCO objects as view models, you would essentially be showing your private objects and break the encapsulation. This in turn would make your model hard to change without altering the corresponding views.
Your data objects may contain details that are appropriate only to the data access layer. If you expose those things to the view, someone might alter those values that you did not expect to be altered and cause bugs.
Many of the same reasons as for having private members in OO languages apply to this reasoning. That being said, it's still very often broken because it's a lot of extra work to create all these "throw-away" models that only gets used once. There exists frameworks for creating these sorts of models, though the name eludes me, that can tie objects together and pick out the interesting properties only which takes away some of the drudgery from creating specific view models.
Your View Model tells the View how data should be shown. It expresses the model. I don't think its necessary to have two view models unless you have two ways to express your model. Just because you have two pages, doesn't mean you will be showing the data any different way, so I wouldn't waste time making two mini View Models when it can be in one reusable view model, Imagine if later you have a page that needs Name and Age, you would create another view model? It's absolutely silly. However, if you had two pages both showing 'Age' and it needed to be shown in a different way, then I would create another one.
I've read that best practice dictates fats models, skinny controllers.
Models should contain business logic such as getting a list of customers based on parameters sent from a controller.
Controllers should contain just enough logic to invoke methods within a model to return to a view.
However I see many examples and tutorials where there is logic within the controller such as a query that accesses a db to get a list of products. I was under the impression that the logic should live in a method inside a model. The controller can then invoke this method, rather than containing the actual logic to query the database.
So if I have a ProductController I might have a Index action which returns an Index View, and I would have a ProductModel which would house my logic to display certain products based on a query string(which the ProductController would pass to said model). Right?
So if I have a ProductController I might have a Index action which returns an Index View, and I would have a ProductModel which would house my logic to display certain products based on a query string(which the ProductController would pass to said model). Right?
That is correct. As per the Model-view-controller architecture:
The model manages the behavior and data of the application domain,
responds to requests for information about its state (usually from the
view), and responds to instructions to change state (usually from the
controller). In event-driven systems, the model notifies observers
(usually views) when the information changes so that they can react.
The view renders the model into a form suitable for interaction,
typically a user interface element. Multiple views can exist for a
single model for different purposes. A viewport typically has a one to
one correspondence with a display surface and knows how to render to
it.
The controller receives user input and initiates a response by making
calls on model objects. A controller accepts input from the user and
instructs the model and viewport to perform actions based on that
input.
Keep the data-related queries and operations in the model; stuff as much as you can in there in accordance with DRY (Don't Repeat Yourself). Make the functions reusable as much as possible so they can be ported into various controllers and used throughout the application as necessary.
The view should contain little - if any - logic outside of view-specific work.
Your controller functions should invoke the model functions required to retrieve and manipulate data, and should be as "thin" as possible (as you pointed out). The smaller and less involved the controller, the easier it will be to add asynchronous features that "don't reboot the application" on the front-end, making for a better user experience. (If you are concerned about this, anyway!)
The Add Controller dialog box in VS 2010 has the option of adding a scaffold with CRUD functions into the controller. This should tell you quite a bit above how the ASP.NET MVC dev. team views this debate.
Say I have a class Student and a Student has a Tutor. On my edit student page I want to display a list of Tutors to pick from.
To do this I will at some point need to hit the Student repository to get the current student and the tutor repository to get a list of all tutors. I'm using Dependency Injection to get my repo instances.
I have a view model class which the controller populates before passing to the view for rendering. I have given that class an IEnumerable<Tutor> which I can use in the view to render a dropdown.
My question: who should populate the list of tutors?
Should the controller be responsible for loading all data, or, should I get the view model class to load it? I can't decide who's concern this is.
Either way, in a more complicated scenario where there are multiple secondary datasets, one of the classes is going to end up with a contstructor being injected with lots or repositories.
It would definitely be the role of the controller as you don't want your viewmodel to be bound to always loading that particular list of tutors.
The interesting problem is, as you said, avoiding having several IRepository instances injected into the constructor and it's a problem with the repository pattern as a whole and some people have gone as far as to suggest the repository pattern is dead.
I don't know if that is the case, but what I would suggest is that you carefully think about how you structure your data access objects so that you avoid situations where you are blindly injecting repositories around, because that can be very detrimental.
What I tend to do is use the IRepository<> instances as a basis for constructing another repository which has a much closer representation to how my application is accessing data.
I usually let the controller worry about populating separate parts of the view model before sending it to the view. There are times when you might use the same view model in multiple places, and not necessarily still want to populate all its fields (in this case, IEnumerable<Tutor>)
I think it makes sense - the controller's responsibility can then be viewed as:
getting the data from somewhere else (repository) and packaging it together as the viewmodel
passing the viewmodel to the view