Rails 3 project structure for UI Models and Data Models - ruby-on-rails

This may be a really stupid question, but I do not have it clear in my mind as to how it is best to manage this so want to put it down here and see what is common practice.
Coming from .net my web applications are never 1 project which is everything, I tend to at least have a data layer project which deals with persisting entities to the database and making these models represent said entity in a DB friendly manner. Then I have my UI project which has its own models which are a representation of the entity for the UI, which may have validation based information and will most likely be a more cut down model only exposing what is needed.
So the main point I am trying to get out here is that although we may have a User entity, the models to represent that may be slightly different in the UI and Data layers...
Now fast forwarding to rails, you create your project and it comes with database connectivity (which I believe can be swapped out to any flavour you want), and validation and a whole manner of other frameworks and functionality. This then seems to imply that I no longer need 2 projects, just 1 as its all included within here and all done for me, so all I need to worry about are making my models.
This is the part where I am a little confused, as lets say I am using ActiveRecord I will need to make my model and inherit from ActiveRecord::Base, then I will need to setup how this model connects to other models etc, so I have my model's data concerns sorted, now I need to setup my UI concerns, about validation and string lengths etc... now where do these go... I am assuming on the same model, but then a model isnt just a simple representation of data, its a blob of stuff containing concerns for databases and views and who knows what else.
It just seems a little odd to put everything within this one place. I know in .net there are plenty of examples where with large object graph representations in the DB the data models are VERY different to UI models, so is it wise to couple them into one model this way, or is Ruby and its frameworks so flexible in this area that you do not have these same problems? If so is there some example or article which can solidify in my mind how you sidestep the normal problems that cause you to separate your concerns to have maintainable code...
=== Edit ===
Just to try and clear up any confusion, in my post when I say my view models and view concerns, I do not mean presentation concerns. I am sorry if it came across that way. What I mean is that I may have (in a normal .net example) a UserStorage model, which has concerns about persisting a User entity. I then in the ui layer have a view which displays many users and one that displays single users in more detail. You may have 2 differing models here a UserSummary model and a UserDetails model, both partially represent a User entity, but are customised for the actual view in question, as you may get to a situation where UserDetails also becomes a composition of a User and a Company entity, which would mean there are 2 storage based classes feeding into 1 view based class.
Within the examples and guides it makes out like you should have 1 view model which deals with these concerns, as well as storage concerns, and in this case it just seems like if I were in the situation where I had a view model that was a composition of a User and Company it would seem odd for this view layer class to worry about its storage, as its never stored as itself, it is stored as 2 separate models in the database/datastore.
This is the REAL problem I am trying to get at here, it seems to be tightly coupling your view to your storage concerns which I am used to being 2 different things which should never be mixed... like putting your main course and pudding on the same plate...

In vanilla Rails, there is no such thing as a "view model".
The models handle all business logic, including query and persistence, association, and validation. You seem to be dismissing validation as a concern of the view, but this is actually a core concern for the integrity of your models: it does belong there.
That's not to say that validation shouldn't happen in the view (client-side) too, but the model has your core business rules and is the place where the validation rules are ultimately checked.
You will want your models to hold most of the logic of your application. This means things like checking if a user is valid or active, finding related records, etc. Pretty much anything that isn't presentational belongs in the model.
In the view, Rails provides helper methods for formatting. These come from modules that are included in the view instance. Helper methods have access to the instance variables of the view (your models) and are used to present them.
In some situations, passing naked models into the view makes it hard to keep things modular and organized. Some people prefer using Presenters to wrap the models before passing them to the view. It can help to organize your code, but it's also an extra layer. Presenters are not standard in Rails, but it's trivial to add this pattern using plain ruby objects or a library like draper if it makes sense for your application.
EDIT: Oh look, a most excellent blog post on just this very topic came up today, from the most excellent Thoughtbot.

In a nutshell:
if it's about the data (storage, integrity, etc.) it goes in the model
if it's about processing/calculating the data (e.g. finding all pending orders) it goes in the model
if it's about presenting the data (pending orders should have a red cancel button) it goes in the view
Since you seem to be an experienced developer, you'd probably benefit from this book http://www.manning.com/katz/ Its geared towards developers that are new to Rails (but not to web programming).
Alternatively, there is a free online tutorial also http://ruby.railstutorial.org/
And of course, the Rails guides are always a good source of information: http://guides.rubyonrails.org/

Not one mention of MVC in your question, you should look into the Model View Controller pattern.
You should also look into how migrations work.

Related

Where does the "business logic layer" fit in to an MVC application?

First, before anyone screams dupe, I had a hard time summarizing it in a simple title. Another title might have been "What is the difference between a domain model and MVC model?" or "What is a model?"
Conceptually, I understand a Model to be the data used by the views and controller. Beyond that, there seems to be a great deal of differing opinions on what makes up the model. What's a domain model, versus an app model, vs a view model, vs a service model, etc..
For example, in a recent question I asked about the repository pattern, I was told point blank that the repository is part of the model. However, I have read other opinions that the model should be seperated from the persistence model and the business logic layer. After all, isn't the Repository pattern supposed to decouple the concrete persistence method from the model? Other people say there is a difference between the Domain model and the MVC model.
Let's take a simple example. The AccountController that is included with the MVC default project. I've read several opinions that the Account code included is of poor design, violates SRP, etc.. etc.. If one were to design a "proper" Membership model for an MVC application, what would that be?
How would you seperate the ASP.NET services (Membership provider, role provider, etc..) from the model? Or would you at all?
The way I see it, the model should be "pure", perhaps with validation logic.. but should be seperate from business rules (other than validation). For example, let's say you have a business rule that says someone must be emailed when a new account is created. That doesn't really belong in the model in my view. So where does it belong?
Anyone care to shed any light on this issue?
The way I have done it - and I'm not saying it is right or wrong, is to have my View and then a model that applies to my view. This model only has what is relevant to my view - including data annotations and validation rules. The controller only houses logic for building the model. I have a service layer which houses all business logic. My controllers call my service layer. Beyond that is my repository layer.
My domain objects are housed separately (in their own project, actually). They have their own data annotations and validation rules. My repository validates the objects in my domain before saving them into the database. Because every object in my domain inherits from a base class which has validation built in, my repository is generic and validates everything (and requires it inherits from the base class).
You might think that having two sets of models is duplication of code, and it is to an extent. But, there are perfectly reasonable instances where the domain object is not appropriate for the view.
Case in point is when working with credit cards - I have to require a cvv when processing a payment, but I cannot store the cvv (it is a $50,000 fine to do so). But, I also want you to be able to edit your credit card - change of address, name, or expiration date. But you aren't going to give me the number or the cvv when editing it, and I certainly am not going to put your credit card number in plain text on the page. My domain has these values required for saving a new credit card because you give them to me, but my edit model doesn't even include the card number or cvv.
Another benefit to so many layers is that if architected correctly, you can use structuremap or another IoC container and swap out pieces without detrimentally affecting your application.
In my opinion, controller code should only be code targeted at the view. Show this, hide that, etc. The service layer should house the business logic for your app. I like having all of it in one place so it's easy to change or tweak a business rule. The repository layer should be relatively dumb - devoid of business logic and only query your data and return your domain objects. By separating the view models from the domain model, you have much more flexibility when it comes to custom validation rules. It also means you don't have to dump every piece of data into your view in hidden fields and push it back and forth between the client and server (or rebuild it on the backend). Your view model will then house only the information relevant to the view - and it can be customized to have bools for view logic or counts or enums so that the view itself isn't cluttered up with complicated logic statements like
<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) &&
Model.SomeObject.SomeInt == 3 && ...) { %>
While everything seems spread out and over-layered, it has a purpose for being architected this way. Is it perfect? not really. But I do prefer it to some past designs of calling repositories from the controller and having business logic mixed in the controller, repository, and model.
I too often wondered how exactly the MVC elements fit in a traditional web application structure, where you have views (pages), controllers, services, and data objects (model). As you said, there are many versions of that.
I believe the confusion exists because of the above stated, widely accepted architecture, which uses the "anemic domain model" (alleged)-anti pattern. I won't go into much details about the "anti-patternness" of anemic data model (you can look at an effort of mine to explain things here (Java-based, but relevant for any language)). But in short, it means that our model holds only data, and business logic is placed in services/managers.
But let's assume we have domain driven architecture, and our domain objects are the way they are expected to be - having both state and business logic. And in this domain-driven perspective things come into place:
the view is the UI
the controller gathers the inputs of the UI, invokes methods on the model, and sends back a response to the UI
the model is our business components - holding the data, but also having business logic.
I guess that answers your main questions. Things get complicated when we add some more layers, like the repository layer. It is often suggested that it should be invoked by the business logic placed in the model (and hence each domain object has a reference to a repository). In the article of mine that I linked I argue that this is not quite a best practice. And that in fact it is not a bad thing to have a service layer. By the way, domain-driven design does not exclude the service layer, but it is supposed to be 'thin', and only coordinating domain objects (so no business logic there).
For the anemic data model paradigm, which is widely adopted (for good or for bad), the model would be both the service layer and your data objects.
In my opinion,
Model -
Should not contain business logic, it should be pluggable(WCF like scenario). It is used to bind to view so, it should have properties.
Business Logic -
It should be placed at "Domain Services Layer", it is separate layer altogether.
Also, will add one more layer here "Application Services".
App Services talks to Domain Services layer to apply business logic and then lastly return the Model.
So,
Controller will ask Application Service for Model and the flow will go like,
Controller->Application Services(using domain services)->Model
The MVC pattern and the Asp.net framework makes no distinction on what the Model should be.
MS's own examples include persistence classes in the model. Your question about membership being in the model. This depends. Are classes in your model owned by something? Is there a link between who logs in and what data is displayed? Is there filtering of data part of a permissions system that is editable? Is who last updated or edited an object part of your domain as in somebody else needs to see it or something for backend support?
The email example is also it depends. Are you familiar with domain eventing or eventing in particular? Do you have a separate service to send emails? Is the act of sending an email part of your domain or is it a application level concern outside of the scope of your system? Does the UI need to know if an email was sent successfully or not? Do emails that fail to send need retries? Does the content of the email sent need to be stored for support or customer service requirements?
These types of questions are overly broad and subjective but I'm answering so you and everybody who voted you up can understand this.
Your requirements/timelines/resources all bleed into your system's architecture. Even the revenue model can have an effect. You also have to consider the pattern you are shooting for. DDD is much different than persistence-as-model applications and all the slop in between are also valid for certain apps. Are you shooting for testing the app? All of this has an effect.

Why should I use view models?

I'm new to developing web apps using ASP.NET MVC. In fact, I'm rather new to developing web apps, regardless of technology.
Currently, I'm working on a project just to get to know the ASP.NET MVC framework better. When reading on SO and elsewhere on the internet, the consensus seems to be that the views should never deal directly with the business objects (i.e. objects implementing business logic and containing associated attributes). Instead, view models should be used. However, this introduces a couple of issues:
Where do I put my validation code?
I need to add code to map between business objects and view models.
In fact, it seems rather cumbersome and I haven't really seen anyone explaining properly why it's a bad idea passing business objects to the views. Could someone please try to explain this (or point to a good explanation)?
Just a clarification; I'm not looking for examples on how to handle the two issues with view models above but simply an explanation on why I should use view models at all.
Where do I put my validation code?
On the view models you should validate everything that's specific to the application like for example the date should be in en-US format culture, ....
I need to add code to map between business objects and view models.
That's why there are tools such as AutoMapper.
Different problems arise when you use directly your domain models in the views:
The views have specific requirements for displaying the data (localization/globalization) so you either end up with spaghetti code in your views or you put this code on your models so that they become less reusable in other applications because you have polluted them with specific presentation stuff
You have different validation requirements based on the view. Let's take for example the case of Add and Update views. In the Add view the Id property won't be needed and it won't be required because you will be inserting a new item. In the Update view the Id property would be required because you would be updating an existing item. It would be difficult to handle those specific validation rules without view models.
The models might contain properties such as IsAdmin and then I am leaving to your imagination the implication of a controller action with the following signature:
[HttpPost]
public ActionResult CreateUser(BusinessObjectUser user) { ... }
assuming that you have hidden this property from the underlying form by not including it.
The business models don't change often whereas the UI could change more often. What if your customer asks you to split your screen in two? The way you present the information changes and the way it is formatted also change. If you use your models directly into the views the spaghetiness of your views becomes worse and worse with every change.
About 60% of the question I am answering on StackOverflow in the asp.net-mvc tag wouldn't have been asked if the OP have used a view model.
Three reasons to why you should use View Models:
Reason 1: Remove logic from your Views
Reason two: Security
Reason three: Loose coupling
Below link may useful:
http://www.codeproject.com/Articles/223547/Three-reasons-to-why-you-should-use-view-models
First off, allowing the Views to have direct access to the Business Objects in ASP.NET MVC introduces some extra security concerns. ASP.NET MVC does a lot of Model binding for you when a user posts a value back to your controller. This can open you up to various kinds of attacks. By introducing a View Model in between, you can be sure that only the fields you are interesting are bound (because the ViewModel will only contain the fields you care about).
As for the other questions:
Where do I put my validation code?
I use DataAnnotations on my ViewModels directly. That allows me to use the Model validation architecture built in to ASP.NET MVC. If there's any validation beyond that I handle it in my controller.
I need to add code to map between
business objects and view models.
True. But using something like AutoMapper can greatly reduce the amount of boilerplate code that you have to write by hand.
MVC is easy to understand and has very little overhead. But those that have used the Model-View-Controller pattern for some time know that it isn't perfect. Not even close. The Model-View-ViewModel pattern offers an interesting alternative.
It is important to understand that the Model-View-ViewModel pattern extends the Model-View-Controller pattern. It isn't a dramatic paradigm shift if you are used to MVC. Even though the advantages of MVVM are subtle, they are profound.
What are some of the advantages MVVM has over MVC?
Better Separation of Concerns
Improved Testability
Transparent Communication

In MVC (Asp.Net MVC specifically), should a model be represented by a single view?

To me, this seems to make little sense, but after reading the information in the following:
http://weblogs.asp.net/scottgu/archive/2010/02/05/asp-net-mvc-2-release-candidate-2-now-available.aspx
http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html
http://blog.stevensanderson.com/2010/02/19/partial-validation-in-aspnet-mvc-2/#comment-35397( specifically some of the comments)
It appears that the idea behind Asp.Net MVC is that you have a one-to-one relationship between models and views. This seems to go against the DRY principle and several other standard programming practices.
For example, lets say you have a user account model and there are two views available to edit it - one for the user himself to edit it and one for the site admin to edit it. The admin has access to an additional field for something internal, required but the user cannot view/edit it. Per the model binding functionality and the beliefs described in the posts referenced above, I would need to create two separate user models, one for each page, and the only difference would be that additional field. This is just a simple example as well, I've got a few that I've seen where it would potentially mean 5 or 6 different models for the exact same object, just a few fields different between each view. That really doesn't make any sense to me.
I did not read the posts you mentioned, but there is nothing wrong with having one Model for a couple of views.
I would just have this one UserModel and use it in all Views, even if there are some fields that are not used.
If things get a bit more complicated but Users still have a lot in common you can either use aggregation for the usermodel (User.Address) or use Interfaces (User has fields street , and city and implements IAddress).
Both methods have their pros and cons - with aggregation used in the majority of situations.
EDIT
After reading the posts I saw that they deal with validation. This is a different story.
If you want to use DataAnotations you have to have different classes if validation varies. I dont use DataAnnotations - so I guess your class design might be different.
If you're using annotations, I'd strongly consider one "model" and multiple "viewmodels." We went with a viewmodel approach on our current app and have been reaping the benefits, because our basic model needs to be shown in a couple different views.
There is no official requirement to have only one view per model in ASP.NET MVC. In many cases that would lead to duplication of code.
I personally like to split model-view dependencies, that is, one view per model. It comes down to the fact that you never know how, say, a couple of very similar model-view pairs are going to evolve in the future. If they're separate, you just introduce changes in one and you don't have to "fix" the other views that were dependent on this model, or worse, to take extra work to create own models for them all at once.
TL;DR: Make many view models. They are cheap and flexible.
"This seems to go against the DRY principle and several other standard programming practices."
[Citation Needed]?
MVC doesn't change the fact that in any language or pattern you need to make a view model definition for each separate screen. Whether via attributes, via XML, via toggling web form controls, whatever.
The DRY principal usually pertains to repeating business logic. Repeating a FirstName property across a CRUD screen section really isn't a big deal. Even 5-6 times, whats that? 40 seconds?
If you mistake your view models for object oriented classes and not homoiconisticish screen representations you run the risk of filling them up will all sorts of inheritance and or business logic.
Your not really programming when you make dumb view definitions. This work could easily be done in an Access GUI or defined in XML. The fact that your screen-view-models are in C# just makes it easier to fill them up with data and ship them around and work with tools like WCF and Automapper.

Why it's not a good idea to pass entities as Models in MVC?

We're developing a pretty large application with MVC 2 RC2 and we've received some feedback on the way we're using the Entity Framework's Lazy Loading.
We're just getting the entities in the controller and sending them as models to the Views, that is causing that the view code asks the Database for the navigation properties we are using in it. We have read about this and it appears is not a good design, but we were wondering why?
Can you help us understand this design problem?
Thanks!
The main issue here is coupling. The idea behind a model, which is the "M" in "MVC", is that it has no external dependencies. It is the "core" of your application. The dependency tree of a well-designed app architecture should look something like this:
+---------------------------------------> Views
| |
| |
| v
Controllers ----+-> Model Transformer -----> View Model
| \ |
| \ |
v \ v
Data Access <---- Persistence --------> Domain Model
| /
| /
v /
Mapper ------+
Now I realize it's not exactly convincing to just say "here's an architecture, this is what you should use", so let me explain what's happening here:
Controller receives a request.
Controller calls out to some kind of persistence layer (i.e. repository).
Persistence layer retrieves data, then uses a mapper to map to a domain model.
Controller uses a transformer to change the domain model into a view model.
Controller selects the necessary View and applies the View Model to it.
So, why is this good?
The domain model has no dependencies. This is a very good thing, it means that it's easy to perform validation, write tests, etc. It means that you can change anything else anywhere in your architecture and it will never break the model. It means that you can reuse the model across projects.
The persistence layer returns instances of the domain model. The means that it can be modeled as a totally abstract, platform-agnostic interface. A component that needs to use the persistence layer (such as the controller) does not take on any additional dependencies. This is ideal for Dependency Injection of the persistence layer and, again, testability. The combination of persistence, data access, and mapper can live in its own assembly. In larger projects you might even be able to further decouple the mapper and have it operate on a generic record set.
The Controller only has two downstream dependencies - the domain model and the persistence layer. The model should rarely change, as that is your business model, and since the persistence layer is abstract, the controller should almost never need to be changed (except to add new actions).
The Views depend on a separate UI model. This insulates them from changes in the domain model. It means that if your business logic changes, you do not need to change every single view in your project. It allows the views to be "dumb", as views should be - they are not much more than placeholders for view data. It also means that it should be simple to recreate the view using a different type of UI, i.e. a smart client app, or switch to a different view engine (Spark, NHaml, etc.)
Now, when using O/R Mappers such as Linq to SQL or Entity Framework, it is very tempting to treat the classes they generate as your domain model. It certainly looks like a domain model, but it is not. Why?
The entity classes are tied to your relational model, which over time can and will diverge significantly from your domain model;
The entity classes are dumb. It is difficult to support any complex validation scenarios or integrate any business rules. This is referred to as an anemic domain model.
The entity classes have hidden dependencies. Although they may appear to be ordinary POCOs, they may in fact have hidden references to the database (i.e. lazy loading of associations). This can end up causing database-related issues to bubble up to the view logic, where you are least able to properly analyze what's going on and debug.
But most importantly of all, the "domain model" is no longer independent. It cannot live outside whatever assembly has the data access logic. Well, it sort of can, there are ways to go about this if you really work at it, but it's not the way most people do it, and even if you pull this off, you'll find that the actual design of the domain model is constrained to your relational model and specifically to how EF behaves. The bottom line is that if you decide to change your persistence model, you will break the domain model, and your domain model is the basis for just about everything else in your app.
Entity Framework classes are not a domain model. They are part of a data-relational model and happen to have the same or similar names that you might give to classes in a domain model. But they are worlds apart in terms of dependency management. Using classes generated from an ORM tool as your domain model can only result in an extremely brittle architecture/design; every change you make to almost any part of the application will have a slew of predictable and unpredictable cascade effects.
There are a lot of people who seem to think that you don't need a cohesive, independent domain model. Usually the excuse is that (a) it's a small project, and/or (b) their domain model doesn't really have any behaviour. But small projects become large, and business rules become (far) more complicated, and an anemic or nonexistent domain model isn't something you can simply refactor away.
That is in fact the most insidious trait of the entities-as-model design; it seems to work fine, for a while. You won't find out how much of a mistake this is until a year or two down the road when you're drowning in defect reports and change requests while desperately trying to put together a real domain model piecemeal.
One potential issue with this design is that the view might iterate through the model objects (that are lazy loaded) more than once and cause an unnecessary overhead. For instance, if a Web page displays the same data in two different forms in a couple of different locations in the page, it'll loop through the query twice and causes two round-trips to the database (Look at the tags under the question and in the sidebar on this page and assume they came from a single query). The view could deal with this problem by caching the results once and loop twice on the cached data, but this is not what a view should deal with. It should present the data given to it without worrying about these stuff.
The problem is that your UI is tied more directly to your entity than necessary.
If your entity is encapsulated by a ViewModel, then your UI can not only contain the entity (the data it wishes to eventually save), but it can also add more fields and more data that can be used by the controller to make decisions, and be used by the View to control the display. In order to pass the same data around outside of a ViewModel would require that you use action method parameters and ViewData constructs, which does not scale, especially for complex ViewModels.
The view is stupid and ignorant. It should not and doesn't want to know anything. Its very shallow and focusses only on display. This is a good thing, as the view does what it does best.
By doing it your way, you leak, what should be data concerns, to the view, and furthermore you limit you view only to recieve data from your entity as the strongly typed model.
Furthermore you let you dependency on EF go all the way to the view and penetrates you app, where you should try to be as loosely coupled to that dependency as you can.

How to represent cross-model information in MVC?

I have an application, built using MVC, that produces a view which delivers summary information across a number of models. Further to that, some calculations are performed across the different sets of data.
There's no clear single model (that maps to a table at least) that seems to make sense as the starting point for this, so the various summaries are pulled from the contributing models in the controller, passed into the view and the calculations are performed there.
But that seems, well, dirty. But controllers are supposed to be lightweight, aren't they? And business logic shouldn't be in views, as I have it as present.
So where should this information be assembled? A new model, that doesn't map to a table? A library function/module? Or something else?
(Although I see this as mostly of an architectural/pattern question, I'm working in Rails, FWIW.)
Edit: Good answers all round, and a lot of consensus, which is reassuring. I "accepted" the answer I did to keep the link to Railscasts at the top. I'm behind in my Railscast viewing - something I shall make strenuous attempts to rectify!
As Brian said, you can create another model that marshals out the work that needs doing. There is a great Railscast on how to do this type of thing.
HTH
Controllers don't have to map to specific models or views. Your model doesn't have to map one-to-one to a database table. That's sort of the idea of the framework. Separation of concerns that can all be tested in isolation.
Why not create a model that doesn't inherit ActiveRecord::Base and execute the logic there (think the Cart class in Agile...With Rails).
Controllers don't have to be that lightweight.
However if you have some calculations that only rely on the model/s then you probably just need some sort of model wrapper for the models to perform the calculation. You can then place that into the API for the view so the view gets the end result.
You don't want the logic to be in the view. However you are free to create a database view. Except, rather than create it on the database side, create it as a new model. This will enable you to perform your calculations and your actual logic there, in one place. The pain of trying to keep your views in sync vs. the one time "pain" of creating the new model... I vote for a new model.

Resources