mvc architecture ruby on rails - ruby-on-rails

In Ruby on Rails, MVC architecture is designed in such a way that, the controller will receive the request and talk to model to receive data and again controller will talk to view to generate html. Now my doubt is, why should model reply to controller and then controller to view, rather than model directly replying to view to generate html. Why was it not designed in that way?
Can someone please clarify? Thanks in advance.

... model directly replying to view to generate html ...
And what if tomorrow you need to generate JSON? And then XML? And other 10 formats? Will you update model each time?
Model, View and Controller have distinct responsibilities.
Model - business logic. Saves and loads data.
View - renders data in a specific format.
Controller - mediator between the two. Parses requests, does authentication/authorization, asks model for data, calls appropriate view with that data.
There should be no business logic in views, rendering in models, etc. This helps for better, cleaner code.
In my hypothetical example, you just need to add a view that can render JSON representation of data. And, probably, add one or two lines to controller (often you don't have to). Model is left unchanged. Its concern is data persistence, not data presentation.

Related

How to handle 2 controller and models with nearly the same data in MVC?

I am starting with MVC since a few weeks and now I have a best practice question:
I have basic data of my project, which are around 30 to 40 propertys, mostly strings.
I have a model with all my propertys for this data called "GeneralDataModel" and of course a Controller "GeneralDataController" and my View "GeneralDataView".
Now I want to have a setting page for this data.
I created a view (GeneralDataSettingView) a controller (GeneralDataSettingController) and a Model (GeneralDataSettingModel).
In fact, most of the data are the same, e.g. I have to load all data into the model when the view is loaded to display them in my TextboxFor.
Some methods are not the same, e.g. a method to save my data which only my setting page but not the display page have.
I know a few methods to have not the same model data and controller methods over and over again - e.g. I could work with inheritance, I could simply extract the methods in a class above where both controllers have access too...
What is the best practice here?
I don't like the "pull data for all views in group" approach, especially if you have to hit multiple tables and pull data you are not using in a particular set of data in a specific view.
One pattern that can work, depending on your need, is pull the common data and then use a decorator pattern to pull the additional data. But jumping to decorator can be dangerous, as it leads you to try to use it everywhere.
I like the "solve for each page and then refactor to patterns" approach, as you are not trying to then make things fit to the first pattern you find (ie, the hammer searching for nails methodology). But, if you have the pattern that shows a pattern like decorator solves the problem efficiently, then go that direction.
Hope this helps.

How should we pass a data to a view in a big ASP.NET MVC web site

First of all, I have been a php programmer for a long time and I am a mvc programmer newly. I did a few minor web sites that each have one or two controller at most. But I've started a website that will be very major web site. There will be a lot of data to pass to views.
Now, normally I try to use model approach every time instead of ViewBag or ViewData approach. If the view demands more data, then I change the model class and then recompile the project. Especially, if the topic is an index page, the data to pass to the index's view changes every time. In a big web site, I'll use a lot of partial view that uses different models. So every time, I will have to change the index's model to support those partial views in the index view. if I add a new partial view into index view, I have to add the partial's model into the index's model.
I implement an IndexModel class for an index view every time when I start a website. Then I add properties to this model every time when I add a new partial view to the index.
Now is this a correct approach or should I use ViewBag or ViewData for partials' models. I think the real question is when we should use the model approach and when we shouldn't...
If you share your experiences, I would be grateful.
The MVC approach you should use always, especially for simple sites, it's save your time and make application more understandable.
If you write something larger than two pages, you need to use MVVM pattern (growth of MVC), in that case you will escape from using "partial models" with ViewModels.
Model must contain only busines logic.
Be better if you will always use ViewModel (not a Model) for returning data from a view and pass it to view, because it provides some safety.
For facilitate the procedure of copy data from Models to ViewModels use the things like AutoMaper and EmitMapper.
ViewBag and ViewData you should use only for additional data's like item colections for DropDown, or some view-text like page title.
One more advantage of MVVM pattern is better testability. If you write and support really hugh site you may write tests for some responsible parts of code.
For more details you can look at google - MVVM, ASP-MVC.
If i something not understad in you question or miss, write it in the comment ("add comment" ref).
I personally prefer to keep my sites consistant and always use Model + Viewmodel (no matter how big the site is) despite the extra work (which isn't much anyway).
It helps with maintainability. I know where and how everything is stored and coded into the site.

Is it considered bad practice to write db queries in a controller rather than a model

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.

MVC: I need to understand the Model

I've been working with the MVC pattern for a while now, but I honestly don't feel like I truly understand how to work with and apply the "Model" ... I mean, one could easily get away with using only the Controller and View and be just fine.
I understand the concept of the Model, but I just don't feel comfortable applying it within the pattern... I use the MVC pattern within .NET and also Wheels for ColdFusion.
"the Model represents the information (the data) of the application and the business rules used to manipulate the data" - yes, I get that... but I just don't really understand how to apply that. It's easier to route calls to the Controller and have the Controller call the database, organize the data and then make it available to the View. I hope someone understands where my confusion resides...
I appreciate your help in advance!
Look at it like this. When your client requests a page this is what happens (massively trimmed):
He ends up at your controller
The controller gets the necessary data from your model
The controller then passes the data to the view which will create your HTML
The controller sends the HTML back to the client
So client -> controller -> model -> controller -> view -> controller -> client
So what is the model? It is everything that is required to get the data required for you view!
It is services
It is data access
It is queries
It is object mapping
It is critical 'throw exception' style validation
Your controller should not be writing your queries if you are sticking to the pattern. Your controller should be getting the correct data required to render the correct view.
It is acceptable for your controller to do a few other things such as validating posted data or some if/else logic but not querying data - merely calling services (in your model area) to get the data required for your view.
I suppose it's just what you decide to call the different bits in your application. Whichever class you use to pass information from the Controller to the View can be seen as/called "The Model".
Typically we call Model our entity classes, and we call View Model the "helper" classes, for lack of a better word, we use when a "pure" entity (i.e., one that will be stored in the database) doesn't suffice to display all the information we need in a View, but it is all mostly a naming thing.
Your model classes shouldn't have any functions; ideally a model class will have only properties. You should see model classes as data containers, information transporters. Other than that they are (mainly) "dumb" objects:
// This would be a model class representing a User
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
How do you actually pass information (whatever that might mean in your context) form your controller to your View and vice versa? Well then, that's your model. :)
Here is the way I have explained before:
Controller: determines what files get executed, included, etc and passes user input (if any exists) to those files.
View: anything that is used to display output to user.
Model: everything else.
Hope that helps.
Model is the code representation of your base Objects. While some less data-intensive systems may be light on the model end of MVC, I am sure you will always find an applicable use.
Let's take a contrived (but realistic) example to the usefulness of a model:
Say I am making a Blog. My Blog has Post objects. Now, Posts are used in and around the site, and are added by many users in the system. Our system was coded for people to enter HTML into their posts, but low and behold, people are starting to add pasted text. This text uses "\n" as the newline character.
With a model, this is a relatively simple fix. We simply make a getter that overrides postText:
public function get postText() {
return this.postText.replace("\n", "<br />");
}
Suddenly, we can affect behavior across the entire site with a few lines of simple code. Without the implementation of a model, we would need to find and add similar functionality where ever postText is used.
The Model in MVC is all about encapsulation and flexibility of a codebase as it evolves over time. The more you work with it and think about it in this manner, the more you will discover other cases that would have been a nightmare otherwise.
--EDIT (you have added to your question above):
Let us take this same example and use your Controller calling the database. We have 9 Controller classes for vaious pages/systems that use Post objects. It is decided that our Post table needs to now have a delete_fl. We no longer want to load posts with delete_fl = 1.
With our Post model properly implemented, we simply edit the loadPosts() method, instead of hunting down all the cases across the site.
An important realization is that in any major system, the Model is more of a collection of files than a single monolith. Typically you will have a Model file for each of your database tables. User, Post, etc.
model: word, sentence, paragraph
controller: for (word in sentence), blah blah... return paragraph
view: <div>paragraph.text</div>
The idea is to separate the concerns. Why not just have the controller logic in the view as well? The model represents the business objects, the controller manipulates those objects to perform some kind of task and the view presents the result. That way, you can swap an entire view for a different one and you don't have to rewrite the entire application. You can also have people work on different layers (model, controller, view) without affecting the other layers to a significant degree.
By combining the controller and the model, you are making your code less maintainable and extensible. You are basically not performing object-oriented programming as you are not representing the things in your database as objects, you are just taking the data out and sending it to the view.
The model contains business logic (i.e. significant algorithms) and persistence interaction - usually with a database. The controller is the MVC framework: Wheels, Struts, .NET's MVC approach. The view displays data that the controller retrieves from the model.
The big idea going on with MVC is that the view and model should be unaware of the controller - i.e. no coupling. In practice there's at least some coupling that goes on, but when well done should be minimal, such that it allows for changing the controller with low effort.
So what should be happening is a request hits the controller, typically a front controller, where there should be some glue code that you've written that either extends some controller object or follows some naming convention. This glue code has the responsibility for calling methods on the correct service layer object(s), packing that data inside of some sort of helper - typically an Event object - and sending that to the correct view. The view then unpacks data from the Event object and displays accordingly.
And when done well, this leads to a domain model (a.k.a. model) that is unit testable. The reason for this is that you've divorced the algorithms from any framework or view dependencies. Such that you can validate those independently.

best practice for what is in a ViewModel

I am wondering if it is a good idea or bad, placing things like a List of countries in ViewModel, for binding to a drop down list? For example on a site's Registration page.
I was under the impression that a ViewModel is supposed to represent an instance of the filled out form, but I think I may be wrong as I have seen other people put things like lists in their ViewModel.
Would it not be better to put it in a static class somewhere and called directly from the View?
Like CommonData.ListCountries(); and then using Lambda to convert to SelectList item list in the view Directly?
As you've realized there are a variety of ways to accomplish your goal. While the MVC design pattern encourages certain application organizations how you organize your models, views and controllers is ultimately a matter of preference.
Scott Allen discusses his preference for dealing with ASP.NET MVC drop down lists in a blog post. Scott uses an extension method to convert an enumerable of a complex type into an IEnumerable<SelectListItem> on his model. He then describes that upon post back ASP.NET MVC will not be returning the IEnumerable<SelectListItem> he sent to the view, but only the value the user selected. He then suggests that utilizing two models can simplify things.
This is a reasonable description of what I refer to as ViewModels and FormModels. A ViewModel carries the display data to the view and a FormModel is used for carrying collected data back to a controller action. To explain further:
ViewModels contain data that help render views. By organizing my ViewModels this way I can place all necessary information to render a particular view into an associated model. This prevents me from having to use ViewData for anything that's not truly temporary.
FormModels are used to gather user input. FormModels (almost) never contain references to other complex types and are made up of primitives, DateTimes, and strings.
In either case I have a hard rule to never reuse a model for a different view. Having your models closely aligned with the views used to render them makes your views easier to write. You don't have to worry about things like static methods because your models should be carrying data to their associated views in a form that is easy for them to render. Tools like AutoMapper can help "flatten" domain objects into models for display purposes.
For additional reading checkout: ASP.NET MVC terminology is tripping me up - why 'ViewModel'?
Whatever data your View needs, put it in the ViewModel.
The way i see it, once your view is going through the rendering process, it should have all the info it needs from the Model it is bound to.
If you start to use helper methods, then the View is "going back to the controller" in a sense. Extension/helper methods are fine for formatting, etc, but they should not call through the model.
Don't forget, you also have ViewData (basically HttpContext.Current.Items, lives for single request), which is a lightweight storage mechanism that can be used to share data across partial views (for example).

Resources