As a neophyte Ruby on Rails programmer, there are certain phrases, acronyms, and slogans one hears incessantly. “REST”. “CRUD”. “DRY”. “Convention over configuration.” “MVC”. These concepts are all central to Rails — and, to an extent, web development more broadly — but at first glance can easily seem inscrutable.
Today, I’d like to focus on just one of these acronyms — MVC — and write about it from the perspective of a Rails greenhorn. I’ll illustrate my overview with a few code examples, drawing on the classic Rails example of an input form.
To start with the basics: MVC stands for “Model, view, controller”, and represents a strategy for developing interactive software programs. In it simplest form, what the MVC structure does is draw a line between presentation (how your application looks to a user) and data processing (what gets inputted and outputted from your database).
To put this in even more basic terms: MVC helps you, as a programmer, figure out where code belongs. And as a result, it makes your application easier to create and easier to maintain.
Let’s take a look at how MVC works by taking up a concrete example: A user sign-up form.
“V” — The View
In Rails, forms belong in the view, the “v” in MVC. The code below represents a (very) simple user sign-up form with two fields: “name” and “email”.
<%= form_for @user do |f| %> <%= f.text_field :name, :placeholder => "Name..." %> <%= f.text_field :email, :placeholder => "E-mail..." %> <%= f.submit "Sign up" %> <% end %>
Just having this code alone wouldn’t do much. Note that there’s nothing here to define the @user instance variable, and there’s nothing that explicitly tells the application what to do when a user clicks on “submit.” Fortunately, with just a little bit of coding, a lot of under-the-hood Rails goodness, and some understanding of MVC, we can get this form working.
“C” – The Controller
When a user clicks on the “submit” button in the view, your Rails app will turn to the controller. The controller is Rails’ middleman — its role is to interpret inputs from the view, use those inputs to interact with the database, and return the right data back to the view.
For our example above, our users controller would look like this:
class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(params[:user]) @user.save redirect_to @user end def show @user = User.find(params[:id]) end end
To “translate” the above into English — in order to have things work, we need to define three things in the controller: What shows up on the original view page, what happens when we submit the form, and what happens after the data is inputted to the server. We do this through three controller actions: “new”, “create”, and “show”.
When a user submits a signup form, Rails by default looks to the create action in the relevant controller (if Rails detects that a record for the user already exists, it very intelligently routes the submission to the update action instead). What our create action does is very simple: It defines a new user based on the form inputs (the params[:user]), saves that user, and then serves up the user’s “show” page (which is just another view).
“M” — The Model
And so we’re done, right? Not without what is perhaps the most important piece of the puzzle: the model. The model does the actual work of interacting with the application’s data. All the controller does is tell us what data to look for; the model goes in and actually handles that data — and makes sure that that data is valid.
Let’s take a look at our Users model.
class User < ActiveRecord::Base attr_accessible :name, :email validates :name, presence: true end
The model that we’ve created here does a few things. First, the model is interacting with a database column called “users” through a central piece of Rails magic called ActiveRecord::Base. Second, the model is determining which attributes the user can input from the view — this is what’s going on in the attrc_accessible line. And finally, the model is setting some restrictions on the form data entries can take (in this case — through “validates :name, presence: true — ensuring the presence of a name in the form).
Back to the Controller & View
MVC is a two-way street. After interacting with the database, the model shoots its information back to the controller, which then sends it back to the view. In our case, provided that the inputted information was valid, the controller will redirect the user to his or her “show” page, which we’ve defined above. This will require a new view template in apps/views/users/show.html.erb.
If there’s a moral to the story, perhaps it’s this: For an initiate to the world of Rails programming, acronyms and matras like DRY, REST, MVC, “convention over configuration”, etc. etc. can easily send a skittish reader packing. The truth is, though, that Rails is set up to help you learn. And MVC architecture is an essential part of that.
A final disclaimer: If it isn’t abundantly clear already, please note that I’m by no means an “ace” Rails programmer and none of this should be read as an authoritative exposition to the subject. Rather, my aim here is to communicate some lessons I’ve found helpful on my learning path. I hope some of it may be helpful to others.
I drew primarily from two sources for this blog post. I highly recommend both as excellent resources for Rails beginners.
Sam Ruby; Dave Thomas; David Heinemeier Hansson. Agile Web Development with Rails, The Pragmatic Bookshelf, Chapter 3.
Michael Hartl, “Ruby on Rails Tutorial: Learn Rails by Example”, http://www.railstutorial.org. (See pages 82-83 for a particularly excellent illustration of MVC at work.)