Model View Controller: theory and practice

Torsten Ruger
rubydesign_web
Published in
6 min readAug 22, 2017

This article is part of a series for beginners. If you haven’t read the previous one, where we build a simple app, i suggest you do.

When we solve recurring problems with the same or similar solution, we call that solution approach a pattern. Studying patterns is not only a good way to become a better developer, it also helps us think and talk about problems at a higher level. Instead of saying “a flat surface to put things, usually with four legs”, we can suddenly say “table”.

One of the oldest and most used patterns, discovered when building desktop application in the 70’s, is called model, view, controller, or short MVC. It is a way to break the responsibilities of a system up into those three parts, and define certain ways for those parts to interact.

Request response flow in MVC

The main thing to notice in the diagram is the flow of control between controller, view and model. Specifically:

  • the controller uses the model
  • the controller also uses the view
  • the view also uses the model
  • the model does not use controller or view

In fact, the model is quite unaware of the existence of controller or view. It is also the gatekeeper of the database, in other words controller or view do not use the database directly, only through the model.

The model layer is where we build a representation of our domain problem. The view visualises the problem, by using the model. The controller orchestrates which view to use when a user requests it.

The exact steps for a request response cylcle in this MVC architecture are:

  • the client (browser) requests a certain url
  • a router (not shown) determines which controller to use and forwards the request to the contoller.
  • the controller uses the model to either create and existing or new model instance.
  • the model layer uses the database to find or save data and instantiate instances
  • the controller instantiates the appropriate view, this depends mostly on the user request
  • the controller renders the view, which creates html, and sends that back to the client

What the diagram shows is the MVC pattern, as applied in rails. This is slightly different from the original, as “views” in rails are not the live objects(that receive user interaction) that MVC was created for. The idea is that once they the html has gone to the client and is rendered by the browser, the html will be a view.

Models in rails

The greatest benefit the MVC pattern gives us is the coherent and self contained model layer. Models and their relationships represent real world entities and the functionality we define on them represent the aspects of the real world that we want to capture in software.

For software to be useful it must save it’s state, and this is normally done in a database. Normal, ie relational, databases are quite passive stores, in many ways like a collection of big exel sheets. Databases have no domain functionality, this is defined in the model. Having only one place to do one thing, ie the model layer, helps to keep the data in the database consistent.

In rails, all interaction with databases goes through a layer called ActiveRecord, and our application models inherit functionality from ActiveRecord. There are many ways to add models, ways to use the database in rails, and the easiest is again to let rails generate code for us. We could use rails generate model ModelName to generate a ModelName, but we can do even better than that.

Rails also has a generator called scaffold, that can generate a model, view and controller at the same time. The code that is generated implements the very common CRUD case, which stands for create, update and delete. Let’s start with a very simple model for a user, since most applications will have a user. We will start very simple, and just have a name and email for the user, knowing that real users have passwords and more, which we will add later. The command to generate the code is:

> rails generate scaffold user name email:uniq

The uniq makes it so that users emails have to be unique. After a colon you can also specify a different type than the default string. Again a lot of files are generated, some of which we know (controller and views), but some we don’t. The model class is defined in the file app/modes/user.rb , and if you open that in your editor you may be surprised to see it empty.

The model is empty because of two things: Firstly, there is a migration file created. It is found in the db/migrate/ directory and will be named with a timestamp followed by create_user.rb, something like 20170815183543_create_user.rb. It defines that the user will have a name and an email. Or to be precise it says the database shall have a table called users, and this table shall have columns name and email. Rails, or ActiveRecord really, will make objects out of the rows of that table.

The second reason that the model class file is empty, is because of a rails principle called DRY, don’t repeat yourself. Our model definition is in the migration file, so it is not repeated in the model file. If it were, and we would change only one, which one would be right ? This may at first sound like an easy thing to avoid, but in a team of 10, working over a year, new people coming, others leaving, deadline stress, changing requirements, you can start to imagine that any way you can avoid mistakes is a good way.

The migration file defines a change to the database. To actually apply that change, we have to use the rails command again

> rails db:migrate

Now the database will have users, and we can see the created functionality at localhost/users . Off course you have to start the rails server if it wasnät running by

> rails server

If you follow the new link you will be able to create a new user, then you will be shown the user and you can go back to the list of users. There you will see the user and can edit, view or destroy it. All the promised CRUD functionality is there, even if it doesn’t look very modern. The scaffold code is really just meant for learning, possibly as a starting point.

Rails MVC recap

This is so important stuff, it really does not hurt to go over what we learned one more time.

The model layer is independent of other layers and defines the data structures of an application and the operations on it. It stores and retrieves data from the database and keeps the database consistent.

A controller receives user input and finds and/or creates the models needed. It also determines which view to use and makes the model available for the view to use.

Rendering the view creates the html that the controller returns to the user.

  • app/controllers is the directory where controllers are found. HelloController will be in a file hello_controller.rb , by convention.
  • public methods on controllers are called actions
  • by default an view of the same name as the action will be rendered
  • views are in found in a subdirectory named after the controller, of the directory app/views/ eg app/views/hello/for all views of the HelloController
  • models are found in app/models in file named after the model.
  • models inherit functionality from ActiveRecord that allows us to store them in and retrieve them from a database

The next article, the last really, will be about publishing an app.

--

--