It’s not a secret, putting business logic inside a view is a bad idea. Views should only contain HTML and presentation logic.
This is bad :
some html here
<% if(@my_nbr * 2) > 55 -%>
Some more HTML
<% end -%>
This is better :
some html here
<% if(@number_big_enough) -%>
Some more HTML
<% end -%>
This is VERY bad :
some html here
<% if User.find_by_name("john") -%>
The view is interacting with the model... not good.
<% end -%>
this is better :
some html here
<% if @john -%>
@john has been resolved in the controller
<% end -%>
Consider the view as your most stupid MVC component (I’m sorry, view. I didn’t want to make you cry). Aside from “if” and “each”, the “V” component just doesn’t understand ruby code that much. That’s why you should set convenient instance variables in the controller that the view will find easy to use. When the view is rendered, every business rules must already have been resolved in the controller. The view don’t want to think by itself, it wants to be instructed what to do.
Moreover, a view should never interract with a model. The view is completely clueless about database related stuff. When it wants to know what to display, it queries the variables that have been set by the controller (with it’s very limited ruby knowledge) and expects a simple yes/no answer.
When the view needs to iterate through a collection, that collection must have been created and tested by the controller. The view just knows how to loop and how to display stuff, not how to fetch data.
I know that all of this may be pretty basic stuff to you, but sometimes it can be tempting to make a view looks more intelligent than it should. Views shine when they are clueless and stupid about everything that isn’t related to presentation in the same way that models shine when they are clueless and stupid about the application flow. When you think about it, the remaining component is the only smart guy out there. The controller knows how to query the model and how to prepare instance variables that will be consumed by the not so smart view. In fact, the controller is the only component able to see “the big picture”.
So let’s keep our views simple and stupid!
#UPDATE 04/28/2007
Dan and Alan made me realize that I didn’t talk about helpers. Helpers are indeed very handy when you want to keep your view clueless about all the nitty gritty details of your application. Instead of letting the view works by itself, it can remain lazy and instead call services (helpers) that will do all the complicated stuff and return a nice and ready to display result.
I would take this a step further and say “No instance variables in the view”.
I try to keep all view type logic within my helpers, and just include the appropriate helper method when needed. The view should not have any real knowledge about how the controller’s internal state, which is (unfortunately) copied into the view’s namespace.
You’ve probably heard of “Fat Model, Skinny Controller”, I try to do “Fat Model and Helpers, Skinny Controllers and Views”.
I agree with you. But the question is why?
I imagine keeping logic out of the views and using helpers whenever it makes sense in the view will keep the view easier to maintain.
@Adrian,
It’s just a “separation of concerns” thing.
Views duty is to manage the presentational side of things
Models duty is to manage the backend storage
Controllers duty is to manage the application flow
@Dan , @Alan
I should have talked about helpers, you’re right! I will update my post.