I am a bit confused on what to write where in Rails.
Ideally, I will be having a view, a controller, a model. Model should be having all the business logic. But in most of the Rails applications I've seen, I've seen most of the business logic written in the Controller files.
Should we call them as controller? And what about View-models. I am talking about the datamodels that are associated for a view. I am having JSF and Swing in my mind when I say this. There every view has a datamodel associated with it, usually a bean. But here, we don't have anything like that or I am ignorant? And what about service layers, How do I implement them in my Rails code.
To summarize my questions
Why are business logic being
written in Controllers in most of
Rails code? Is this a good practice?
How to incorporate the view-model in
rails, ie, data-models for view?
Where to put service layers in a Rails app?
Thanks
To summarize my answers:
The new standard for Ruby on Rails is to place business logic in the model. This is also known as fat model skinny controller.
Rails doesn't enforce this approach of one data model but you can implement it if you choose. The basic scaffolding does something similar.
The service layers will most likely be stored within rack middleware. This allows for general filtering of requests and responses.
Related
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.
If I understand MVC correctly Controllers should only contain logic that glue the model together with the view. It contains the application logic such as authentication, session and other things for the application. The model on the other hand should do the business logic of the application and the views should update in response to changes on the model. However, how do you this in Rails?
My controllers contain logic that finds model objects etc and then update the views in response.
Have I misunderstood application logic and business logic. I would apprciate if somebody could help me understand MVC.
Rails is a good implementation of MVC and allows good abstractions. Finding model objects is not business logic.
To make sure you get this right, keep your controllers short; move any significant logic to models by creating new methods; use the built-in rails helpers and methods; follow RESTful architecture where possible (not perfect, but helps) and get someone else to discuss your code with you.
Part of the problem is that the Rails architecture makes it look like model = ActiveRecord, and that's not necessarily true. A Model class or module can be anything you like.
When the models -are- ActiveRecord (which does make sense in the majority of cases), you can add methods to those classes that can be invoked by the controllers and that contain the business logic.
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.
Could someone please explain MVC to me in Ruby on Rails, in layman terms. I am especially interested in understanding the Model in MVC (can't get my head around the model).
Some background, MVC is a (compound) design pattern and was developed in 1979 by Trygve Reenskaug (Smalltalk).
True MVC was primarily planned for use in n-tier (non web) systems and it splits a system into 3 distinct parts, a Model, View and Controller
The Model
Contains data for the application (often linked to a database)
Contains state of the application (e.g. what orders a customer has)
Contains all business logic
Notifies the View of state changes (** not true of ROR, see below)
No knowledge of user interfaces, so it can be reused
The View
Generates the user interface which presents data to the user
Passive, i.e. doesn’t do any processing
Views work is done once the data is displayed to the user.
Many views can access the same model for different reasons
The Controller
Receive events from the outside world (usually through views)
Interact with the model
Displays the appropriate view to the user
** Classic MVC is not suited to web applications, as the model cannot send all changes to the view in an observer fashion (the view is a web page). The Model2 was introduced to overcome the changing infrastructure by JSP team in 90s . MVC Web frameworks are really not MVC, but Model2 (this is true of Ruby on Rails).
Here is a description of GUI patterns including MVC from the master, Martin Fowler
GUI Architectures
The best book I have found so far is Agile Web Development with Rails. It begins by assuming no knowledge, and is quite comprehensive.
Hope this helps to shed some light for you!
MVC basically indicates Model-View-Controller. And MVC used by many languages like PHP, Perl, Python etc. Generally MVC works like this:
Request first comes to the controller, controller finds and appropriate view and interacts with model, model interacts with your database and send the response to controller then controller based on the response give the output parameter to view.
Your Model is the data structure that your program uses.
The View is the part that interacts with the screen or the next level up.
The Controller generally processes data between the model and view
MVC structures are often nested, so a "Model" or "View" may contain its own MVC (Think of a component on the screen. You may just fill it with a string, but behind the scenes the code of the component draws its own little view, has it's own little model (the string you pass in) and has a little controller drawing the data onto the view.
In Rails, the roles of the model, view and controller are well-defined by the framework, any tutorial will point out the three components as it walks you through the files it created.
In other systems, those pieces may be harder to identify. Also, MVC is not "Perfect", just keep in mind that there are valid alternatives, but it's a good way to start organizing.
The Model View Controller principle divides the work of an application into 3 separate but closely cooperative subsystems.
Model (ActiveRecord ):
It maintains the relationship between the objects and the database and handles validation, association, transactions, and more.
This subsystem is implemented in ActiveRecord library, which provides an interface and binding between the tables in a relational database and the Ruby program code that manipulates database records. Ruby method names are automatically generated from the field names of database tables.
View ( ActionView ):
It is a presentation of data in a particular format, triggered by a controller's decision to present the data. They are script-based template systems like JSP, ASP, PHP, and very easy to integrate with AJAX technology.
This subsystem is implemented in ActionView library, which is an Embedded Ruby (ERb) based system for defining presentation templates for data presentation. Every Web connection to a Rails application results in the displaying of a view.
Controller ( ActionController ):
The facility within the application that directs traffic, on the one hand, querying the models for specific data, and on the other hand, organizing that data (searching, sorting, messaging it) into a form that fits the needs of a given view.
This subsystem is implemented in ActionController, which is a data broker sitting between ActiveRecord (the database interface) and ActionView (the presentation engine).
Check the links below for clear understanding of mvc in rails:
http://www.bogotobogo.com/RubyOnRails/RubyOnRails_Model_View_Controller_MVC.php
https://betterexplained.com/articles/intermediate-rails-understanding-models-views-and-controllers/
I think the best way to wrap your head around MVC is by example. Try coding up a simple Rails app using MVC. There are many tutorials online, such as the blog example at "Getting Started with Rails".
If chose to learn by coding an example, check out the answers to Where can I find clear examples of MVC?
MVC isn't specifically just for Ruby on Rails. It was actually created awhile before Ruby on Rails ever came around. It's mainly just a way of organizing your code so that you have some code that's responsible for your models (the Class version of a database table), some code that's responsible for your views (what's visually being displayed to the user) and code that's responsible for your controllers (what ties the views to the models and performs the bulk of your logic.
That's the non-framework-specific description. Each framework that uses MVC has a different way of implementing it. For Ruby on Rails each model represents a database table as a class that can communicate directly in code with other objects without needing to write any SQL. All the SQL is being taken care of in the background and you just have to think of it as though it were a normal class (well almost, it's not seamless yet). The view is mostly HTML and represents what will be sent to the browser. The controller is just the code that communicates the models and views together.
All in all, MVC isn't specific just to Ruby on Rails...that's just the most popular.
Ruby on Rails does not implement the MVC design pattern. Ruby on Rails has folders called controllers, models, and views. The views folder has HTML files. The controllers and models folder have ruby files. The controllers map to a URL and a method in the controller gets executed upon requesting that URL, the associated view (HTML file) gets loaded and the model (data structure) for it is used to populate the view. Thats the extent of it's likeness to the MVC design pattern. It's a shame that people say it's MVC because it's caused a generation of confusion and misunderstanding of the MVC design pattern.
In Rails, the model is a data structure.
Here's a brief overview at a high level on how the MVC Pattern works:
Controller:
Listens on some kind of interaction/event stream.
Controller can send the model that type of interaction/event.
Controller can also communicate with the the view.
Model:
Models will listen in on the interaction/event from the controller.
Is an abstraction of a data source.
Handles data logic and manipulation.
After it is done with logic, it then sends to controller which will then communicate with the view.
View:
View can communicate with the controller.
Knows how to render data from the Model to the browser visually.
The Controller tells to View to do something with something from the
Model.
A couple of things to note is that models can't communicate with views directly and vise versa. Only the controller can communicate with the view and model, so the controller acts as the delegator for the interaction/event retrieved from users interaction on the browser.
check this link for more clear understanding
one more link to get clear
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).