Where does business logic go in rails? - ruby-on-rails

I'm an ASP.NET MVC developer just starting with my first big project on rails however Im confused as where to put your business logic? on ASP.NET I create a library which contains services(Domain driven design) which handle business logic, I have heard that rails uses a concept of fat model skinny controller but I have some projects in ASP.NET which adding all the logic to the controller would create a big mess, is there any other way?

Go with the concept of FatModels and SkinnyControllers. Your models should know how they behave and what they should do.
When your models get too fat, extract them out into re-usuable modules and include them in your module.
Example of taking a fat controller (with logic) and moving to a model
Example of taking code from the views and moving into the model
You can easily test behavior of models using RSpec (or test/unit or shoulda). Then you can test that the application behaves correctly using Cucumber.

"Business Logic" or some might call it "Domain Logic" doesn't belong anywhere near Rails and/or your .NET MVC project. Rails and MVC should depend on your Domain not the other way around. I would recommend reading up on the Onion Architecture from Jeffery Palermo or watch "Architecture the Lost Years" by Robert Martin. (I think that's that talk anyway). There are probably more resources than that, but you'll thank yourself later for treating both Rails and .NET MVC like the 3rd party frameworks they are, and not the main house of your application.

I think this blog article provides a good overview of a strategy of incorporating domain driven design with in the rails framework: http://www.smashingboxes.com/domain-logic-in-rails/
TL;DR
Refactor your classic rails models into repositories, and use a facade layer in the controllers to interact with your domain model.
I'm struggling with this a little my self, and as much as the Fat Controller pattern seems to prevail, anything "fat" in software seems to be a smell, violating single responsibility.

You can put business logic anywhere you want (even in views! though that's a bad idea).
I'd say if the logic is tied to a real-world object, then put it on the model. Otherwise, use the controller. But it's up to you to determine how to do it for your app. Models are for modeling things, and Controllers are for controlling things.

Related

Can someone explain the phrase "Fat model, skinny controller"?

I'm learning Ruby on Rails. I noticed this phrase "Fat model, skinny controller". I'm not sure what that means. Does that mean I have to use more code in model and less code in controller? Can someone explain this?
You understand correctly. Main reason for this recommendation is that you only need process request parameters and initialize model layer in controllers. Business logic need to be implemented in model layer. This allows you to avoid code duplication and made testing easier using unit tests for models.
Also read this and go through whole site for best practices.
In short yes you have the idiom right, although if any piece of code with a defined role becomes bloated it can be a problem and may need some basic re-factoring.
Business logic used in models can be re-used in multiple different routes, or in web-service APIs, or a command-line script. It can also be unit tested without invoking the web server.
The same business logic in the controller can only be used via the web interface.

ASP.NET MVC - Solution Layout Suggestions

I have been working with ASP.NET MVC for a couple of months now and I'm still not happy with the layout of my project's solution. I am trying to construct a mid-sized website CMS that is as portable and reusable as possible and there are some obvious problems in the design of it. I am looking for some advice regarding how I should structure my solution in consideration of separation of concerns. I've found a similar question here, but it doesn't really target some of the issues I am facing.
Right now this is how my solution is laid out:
+Project.Controllers - All Controller classes
P+roject.Controllers.Tests
+Project.Core - Utility classes including repetitive tasks and some configuration handlers (this project needs to be better fleshed out)
+Project.Core.Tests
+Project.Models - Model classes, Entity Framework context, and Repository classes
+Project.Models.Tests
+Project.Web - All Views and Content
One major thing I am currently missing is a place to stick my business logic and I feel I've been wrongly placing business logic in my repository classes as well as intermingling it in controller actions. Obviously, I'm very aware of this problem, I'm just not sure where I should placing my business logic in that solution layout. Does my solution structure need to change or can I safely keep that business logic in my Models project? Also, I really don't like that my EF Context is in the Models class, but I don't know of a way to isolate the data layer code from the Entity Classes needed in my model.
How is everyone else laying out their production ASP.NET MVC solutions?
You might want to check out the layout the S#arp architecture project uses or the onion architecture as used in the Code Camp Server MVC reference application. Both projects have had allot of effort put into them by different people to get a good sepperation of concerns in the context of asp.net MVC and domain driven design.
Personally I'm only learning MVC. My experience comes from ASP.NET WebForms but I would go with the layout proposed in the link you gave. The second answer, that is:
Models
Views
Controller
Services
Tests - one for each project.
I would take EF Context and Repositories out of Models and into a data access layer, Project.Data and put your business objects in Project.BusinessLogic (?).
This gives the benefit of putting the two assemblies (Project.Data and Project.BusinessLogic) in other apps you might build on the same domain. That means your next project has a very useful starting point.
Hope that helps,
Dan

MVC Models & Controllers where what to write

We have started using MVC framework and now we are bit confused where to write business-logic, in controllers or models?
For the project we are going to use WCF layer as DAL.
People have different views on Model & Controller, and think differently of writing business logic either in 'M' or 'C'.
What is the best practice?
I believe we will be accessing WCF (DAL) service in Model and applying all the business logic or filtering and then Controller accessing the data from Model.
These are my rules:
Controller
Mainly Pageflow . Determines what View is displayed next.
Has access to Services ( ie productService.GetProduct(Model.ProductID) )
Model
I have 2 of them.
POCO-Classes - used by all layers (BLL,DAL)
ViewModel - used by View and Controller for stronly typed views.
View
Hopefully mainly easy HTML
I try to have the layout in a way, that it is possible to have different kind of people work at the project: The frontend guy and the backend guy.
The backend guy will do the Service and Repository.
The Frontend guy will do Controller and Views. He also does ajax.
Try to keep -Business- logic and -Application flow- logic separate. Most people tend to mix those together as -business logic-
Most people keep their business logic in the model and this is considered best practice. Steve Sanderson who has written xVal endorses this method.
As I’ve discussed before, validation rules should go in your domain model, because the role of your model is to represent the workings of your business. It ensures that the rules will be enforced consistently, regardless of whether the UI coder remembers them or not.
Check out his post about xVal that talks about the problem you are discussing.
Do not think that model is supposed to be build from data access logic (wcf service in your case) only. I would recommend you to check out Domain Driven Design, it goes well with MVC. Controllers shouldn't contain any business logic. Controller action method should be ~20 or less lines. But that's just my opinion (made up from countless sources).

How should I namespace my models in ASP.NET MVC? Confused about Nerd Dinner

I am learning ASP.NET MVC and I like it. However, I am very confused about the right approach to namespacing my models.
While dissecting the NerdDinner sample app I noticed that everything in the Models folder belongs to the Models namespace. The data mapping classes, repositories, error rule management, etc., belong to the same namespacing level.
I understand that this folder was inspired by frameworks like Rails and friends, and that it is required to justify the M in the MVC title but; doesn't an automatic Model namespace destroy any chances of writing business logic that is both detachable and portable across different systems and implementations?
Should I namespace my business logic below this Model namespace or should I ignore it completely and classify my classes in a more framework independent manner?
Are there any complex and good ASP.NET MVC sample apps out there that would demonstrate this?
I would classify your classes in the way that makes the most sense to you, I suspect they used that namespace in the Nerd Dinner sample app because from a learning stand-point it is nice for a developer to always see that they are in the Model portion of the application.
Personally I don't put anything in the Model folder and create separate projects for my entities (App.Domain) and for domain services (App.Services). I also create .Tests projects for both projects.
My dev-senses told me that we should be refactoring our data models into another project altogether. Some have even gone so far as to create your business entities in yet another project, and have them constituted from the Linq-Sql classes.
I figured Scott and Co. would have gone the way of at least separating the data model from the presentation tier. We all know the benefits of separation of concerns, but it's puzzling me with the way they kept the data model within the MVC app.
Any more suggestions on a more layered way to go?

How should I structure a simple ASP.NET MVC app?

I've been reading a few things about ASP.NET MVC, SOLID and so on, and I am trying to figure out a simple "recipe" for small-to-medium ASP.NET MVC apps that would put these concepts together; the issue that I am most concerned with is ending up with controllers that are too complex and being like code-behind files in webforms, with all type of business logic into them.
I am considering the following architecture, for a small data-driven app:
Controllers: only handle requests, call an appropriate service and return the action result to the View;
Models: POCO, handle all the business logic, authorization etc. Depends on repositories, totally ignorant of persistence infrastructure.
Repositories: implement IRepository<T>, use dependency injection and is where my db code will reside; only receives and returns POCO.
I am considering having services between the controllers and the models, but if they will just pass forward method calls I am not sure how useful it would be.
Finally there should have unit tests covering the model code, and unit+integration tests covering the repository code (following the "red-green" practice, if possible)
Thoughts?
Ian Cooper had a good post on exactly this recently:
The Fat Controller
Simple recipe: (view)Presentation Layer using ASP.NET, (controller)Code Behinds or AJAX Services Layer, (model)Application Services layer, Business Model layer, and Persistance/Data Access layer.
Of course you can slice and dice numerous ways to deal with complexities in order to build a clearly readable and understandable application.
For a recent discourse on the subject, which I have found to be very good, check out this newly published book: Microsoft .NET: Architecting Applications for the Enterprise.
These walkthroughs are quite helpful:
MVC Framework and Application Structure
Walkthrough: Creating a Basic MVC Project with Unit Tests in Visual Studio
Also see: aspnet-mvc-structuring-controllers
Rob Conery has the best answer IMO.
Check out his MVC Storefront Application, which comes with complete source code and video tutorials.

Resources