What is Model-View-Controller (MVC)? (Ruby on Rails perspective)
Tags: ruby, rails
Published: 2020-02-27 13:42:42

Model-View-Controller (MVC) is a software design pattern invented in 1978 by Trygve Reenskaug while he was a visiting scientist at the Learning Research Group (LRG) at Xerox Parc. 

The goal of MVC was to resolve the issue of users controlling a large and complex data set. 

MVC was designed for desktop use but has been adapted for web applications and can be used differently depending on the framework. 

Let's look into the three parts of MVC and how they work together to create a Ruby on Rails application. 


## Controller
In rails, the Control is called Action Controller. (Throughout the blog I will call it Controller instead of Action Controller)

The controller works with the view and the model in a rails application by acting as an intermediary. When an HTTP request is made the controller will determine the correct controller class and method to use. 

Let's generate a scaffold to demonstrate how the controller works in a simple application.

```ruby
# frozen_string_literal: true

class BooksController < ApplicationController
  before_action :set_book, only: [:show, :edit, :update, :destroy]

  # GET /books
  # GET /books.json
  def index
    @books = Book.all
  end
end
```

I have set the root of the application to the books#index route. So when the user reaches the root path of our application, the book's controller will know to use the index method. 

Our index method uses Active Record to pull all the books from our database and stores it in an instance variable. Then we can use our index view to render all books. 

```
<p id="notice"><%= notice %></p>
<h1>Books</h1>
<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Author's First name</th>
      <th>Author's Last name</th>
      <th>Year published</th>
      <th colspan="3">Settings</th>
    </tr>
  </thead>
  <tbody>
    <% @books.each do |book| %>
      <tr>
        <td><%= book.title %></td>
        <td><%= book.author_first_name %></td>
        <td><%= book.author_last_name %></td>
        <td><%= book.year_published %></td>
        <td><%= link_to 'Show', book %></td>
        <td><%= link_to 'Edit', edit_book_path(book) %></td>
        <td><%= link_to 'Destroy', book, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>
<br>
<%= link_to 'New Book', new_book_path %>
```

## View
The job of the view is to present information to the user. To display content from the model that was retrieved using the controller, we need to use a template engine. In the above example, we used embedded Ruby.

We can also use views to send data to our controller. The controller will then use Active Record which works with our model to save data to the database. 

```ruby
 # POST /books
  # POST /books.json
  def create
    @book = Book.new(book_params)

    respond_to do |format|
      if @book.save
        format.html { redirect_to @book, notice: 'Book was successfully created.' }
        format.json { render :show, status: :created, location: @book }
      else
        format.html { render :new }
        format.json { render json: @book.errors, status: :unprocessable_entity }
      end
    end
  end

private

  # Only allow a list of trusted parameters through.

  def book_params
    params.require(:book).permit(:title, :author_first_name, :author_last_name, :year_published)
  end
end
```

The create method above receives input from the new.html.erb file. The new method renders the form and the create method handles the input and stores the input into the database using Active Record. 

## Model
The model uses Active Record to interact with the database to fetch data or to store data in the database. The controller will use Active record to store the data in an instance variable. We have an example of that in our index method in our books controller. 


## Summary of MVC
The controller in a rails application works between the model and the view. This, in theory, allows for a separation of responsibilities in a rails app. 

So when an HTTP request is sent, the controller will call on the correct method to determine whether or not data needs to be retrieved from the model via Active Record or will it post data. After this is determined, the controller will have the correct view displayed to the user.