The Model-view-controller Architecture
The model-view-controller (MVC) architecture that we first encountered in Chapter 1, Introducing Ruby on Rails is not unique to Rails. In fact, it pre-dates both Rails and the Ruby language by many years. However, Rails really takes the idea of separating an application’s data, user interface, and control logic to a whole new level.
Let’s take a look at the concepts behind building an application using the MVC architecture. Once we have the theory in place, we’ll see how it translates to our Rails code.
MVC in Theory
MVC is a pattern for the architecture of a software application. It separates an application into the following three components:
- models, for handling data and business logic
- controllers, for handling the user interface and application logic
- views, for handling graphical user interface objects and presentation logic
This separation results in user requests being processed as follows:
- The browser, on the client, sends a request for a page to the controller on the server.
- The controller retrieves the data it needs from the model in order to respond to the request.
- The controller renders the page and sends it to the view.
- The view sends the page back to the client for the browser to display.
This process is illustrated in Figure 4.3.
Figure 4.3. Processing a page request in an MVC architecture
Separating a software application into these three distinct components is a good idea for a number of reasons, including the following:
- It improves scalability (the ability for an application to grow): if your application begins experiencing performance issues because database access is slow, for example, you can upgrade the hardware running the database without other components being affected.
- It makes maintenance easier: because the components have a low dependency on each other, making changes to one (to fix bugs or change functionality) does not affect another.
- It promotes reuse: a model may be reused by multiple views, and vice versa.
- It makes the application distributable: a distinct separation of code between components means that each of them could potentially reside on a separate machine, if necessary.
If you haven’t quite got your head around the concept of MVC yet, don’t worry. For now, the important thing is to remember that your Rails application is separated into three distinct components. Jump back to Figure 4.3 if you need to refer to it later on.
MVC the Rails Way
Rails implements the concept that models, views, and controllers should be kept quite separate by storing the code for each of these elements as separate files, in separate directories.
Figure 4.4. The
This is where the Rails directory structure that we created back in Chapter 2, Getting Started comes into play. The time has come for us to poke around a bit within that structure. If you take a look inside the
app directory, which is depicted in Figure 4.4, you’ll see some folders whose names might be starting to sound familiar.
As you can see, each component of the model-view-controller architecture has its place within the
app subdirectory — the
controllers subdirectories, respectively. (We’ll talk about that
helpers directory in Chapter 6, Helpers, Forms, and Layouts.)
This separation continues within the code that comprises the framework itself. The classes that form the core functionality of Rails reside within the following modules:
ActiveRecordis the module for handling business logic and database communication. It plays the role of model in our MVC architecture. While it might seem odd that
ActiveRecorddoesn’t have the word “model” in its name, there is a reason for this: Active Record is also the name of a famous design pattern — one that this component implements in order to perform its role in the MVC world. Besides, if it had been called ActionModel, it would have sounded more like an overpaid Hollywood star than a software component…
ActionControlleris the component that handles browser requests and facilitates communication between the model and the view. Your controllers will inherit from this class. It forms part of the
ActionPacklibrary, a collection of Rails components that we’ll explore in depth in Chapter 5, Models, Views, and Controllers.
ActionViewis the component that handles the presentation of pages returned to the client. Views inherit from this class, which is also part of the
Let’s take a closer look at each of these components in turn.
ActiveRecord (the Model)
ActiveRecord is designed to handle all of an application’s tasks that relate to the database, including:
- establishing a connection to the database server
- retrieving data from a table
- storing new data in the database
It also has a few other neat tricks up its sleeve. Let’s look at some of them now.
ActiveRecord ships with a large number of database adapters to connect to a variety of popular database server packages, such as MySQL, PostgreSQL, Oracle, and Microsoft SQL Server.
ActiveRecord module is based on the concept of database abstraction. As we mentioned in Chapter 1, Introducing Ruby on Rails, database abstraction is a way of coding an application so that it isn’t dependent upon any one database. Code that’s specific to a particular database server is hidden safely in
ActiveRecord, and invoked as needed. The result is that a Rails application is not bound to any specific database server software. Should you need to change the underlying database server at a later time, no changes to your application code should be required.
Examples of code that differs greatly between vendors, and which
ActiveRecord abstracts, include:
- the process of logging into the database server
- date calculations
- handling of boolean (true/false) data
Before I can show you the magic of
ActiveRecord in action, though, we need to do a little housekeeping.