Rails tutorials don’t cover MVC (Model-View-Controller design pattern). It’s something so fundamental, something at the heart of Rails, that it warrants a short discussion. So let’s discuss.
MVC is an object-oriented style of programming that promotes a separation of concerns. The concerns are three:
- The data, and what you can do with it (Model concerns)
- What facets of data you see, and how they’re organized
- What aspects of the data can each user group tweak or change? (Controller concerns)
The model represents your business logic–your data, as well as a set of operations on that data. Model encapsulates validation–this way, your data is always valid. For example, you might be modeling a blog, and your model would not allow posts with no title. The model provides different public functions to manipulate the data, functions that ensure that the data is valid. (For a bank, the model’s functions for TRANSFER would transfer money as one atomic operation, and not withdraw money from one account without depositing it into the other account.)
The view represents a certain user group’s view of the model. For example, the administrator of a blog sees a very different view of a blog then an end-user or a blog-poster.
The controller represents the actions you perform on the model–which functions you call on the model and with what settings.
You can already see how MVC gives you a powerful abstraction to dealing with and extending–you can centralize your business logic in one place, and create different views–an end-user view, a power-user view, an administrator view, a wireless-device view, a rich-media view–and controllers for different sets of users.
Now, back to Rails. Most Rails tutorials introduce you to a very naive model of MVC–while they create model classes (such as Post, Comment, and Vote), they also unfortunately encourage you to create model-level controllers–such as a post controller, a comment controller, and a vote controller.
You should avoid this method, and instead focus on a user-level controller. Why? Because user functionality usually cuts across several levels, not one model–for example, an admin user would create new posts and edit comments, while an end-user would only view posts and create comments. Model-level controllers force you to write messy code that jumps back and forth between different controller logic.
What’s worse, if you have to extend your model, or create a new user-group, your code quickly degenerates into a spaghetti-filled mess that’s difficult to develop and maintain.
So be smart, and stick to this rule: controllers represent a single user group. This allows you to quickly create and maintain powerful applications that easily and intuitively model how users access your application.