Learning Rails #1 - MVC
Tags: beginners, ruby, rails
Published: 2022-03-14 23:27:16

> This is the first post of a series called Learning Rails, where I explain everything I learn during my journey to mastering Rails. The role of these series, is to work as a refresher and a place where beginners can discuss.
If you're also learning (or intend to learn) Rails, I highly recommend that you follow the [Getting Started with Rails Guide](https://guides.rubyonrails.org/getting_started.html).

**Before we start, here are some things to note about Rails:**
- **"Convention over configuration"** - You'll realize that Rails does a lot of things _implicitly_ for us, it happens because Rails defaults to a set of conventions. So we can spend more time coding rather than configuring.
- **No need for importing files** - Rails utilizes autoload, meaning that it loads all necessary files during execution.
- **Naming matters** - All my examples follow the naming conventions, but I won't be focusing on explaining them here, the Guides has everything you need to know.

## What is MVC?
MVC stands for Model View Controller and is the architecture used by the framework. In order to learn Rails, you have to understand MVC. I'll give a brief explanation of what each component does (and how to create them), but remember to always read the documentation if you need a deeper understanding.

When creating a project with rails in the command line (`$ rails new <project-name>`), a bunch of folders will be generated. For now, we'll be focusing on the `app/` folder. You can see an explanation for each directory, on the [Rails Guide](https://guides.rubyonrails.org/getting_started.html#creating-the-blog-application).

## Model
The Model class is responsible for our data, it represents an object of our application and it also connects to the database by inheriting the ActiveRecord class. Here we can validate, query, add, update and delete our data from the database.
> ### The Active Record class
The Active Record class is responsible for handling the connection and queries of our database. It is the magic behind writing ruby code for manipulating our database.

**Creating a Model**
On the terminal, run:
```bash
$ rails generate model Article title:string body:text
```
Here we're saying the name of our Model and its attributes joined by `:` with the attribute type.

## View
This is the most straightforward one, it is the visual part of our application, so it includes all of our files that renders the visual part of our application. 

On rails, we generally use ERB(Embedded Ruby) for our views, which is a template engine. This allows us for rendering static pages with all information we want in a easier way, for example, rather than creating manually a list with all articles, we can use Ruby's `#each` method to do that, soon you'll better understand how this works.

**To create a View**, simply go to the `app/views/<Controller Name>` and create a new `.html.erb` file. The filename should match with a controller action.

## Controller
Here is where we bind all of this together, the controller class contains various methods (usually called actions in the context of Rails) responsible for rendering views and handling our models. It acts as the middleman, since it handles requests and responses in our application.

**Creating a Controller**
On the terminal, run:
```bash
$ rails generate controller Articles
```
Remember to always create it with a plural name, following the naming convention.

## Routes
The routes file is where we map all our requests and responses, to create a new route we define the path, HTTP verb and action for our route. The action is actually a method for a determined controller, as I've mentioned before.

Here is the syntax for creating a new route:
```ruby
# In `config/routes.rb`
Rails.application.routes.draw do
  # Every time a GET request is made to the `/articles` path the
  # `#index` method from the articles controller will be called
  get '/articles', to: 'articles#index'
end
```

## RESTful routes
For our routes we'll be using the REST(Representational State Transfer) architecture, which has to do on how we implement our routes. REST consists of 7 routes needed to create a CRUD for our application. 
To better illustrate these routes, let's imagine we have a blog and we want routes to create/read/update/delete(CRUD) our articles. By using the REST architecture to create our routes, it will result in the following:
```ruby
# In `config/routes.rb`
Rails.application.routes.draw do
  # Get all articles
  get '/articles', to: 'articles#index'

  # Get one single article
  get '/articles/:id', to: 'articles#show'

  # Get form view for creating a new article
  get '/articles/new', to: 'articles#new'

  # Create new article
  post '/articles', to: 'articles#create'

  # Get form view for editing an article
  get '/articles/:id/edit', to: 'articles#edit'

  # Update our article
  put '/articles/:id', to: 'articles#update'

  # Delete an article
  delete '/articles/:id', to: 'articles#delete'
end
```
Notice how all the actions follow a naming convention, these are not random, it is actually the standard naming for such routes. We can replace the code above by using the keyword `resources`:
```ruby
# In `config/routes.rb`
Rails.application.routes.draw do
  # This creates all 7 RESTful routes
  resources :articles
end
```
By doing this, ruby will use the naming convention, I've mentioned above, to implicitly create all the 7 RESTful routes and its action calls.

## The Rails Console
The Rails Console is a way of accessing our application via the Command Line, here we can create components and test them.

In the command line, run:
```bash
$ rails console
```
This will open an IRB(Interactive Ruby) instance with Rails and the application code loaded. So we can create a new article by using the Article Model class.
```ruby
# Here I'm assuming there is an article model that contains a
# `title:string` and `body:text`

# Inside Rails console, run:

# This creates a new Article object
article = Article.new('New Article', 'This is a new article.')

# This save our object to the database
article.save

# Quit the Rails console
quit
```
Great! Now that we have an article, we can render it on our page.

## Handling Requests in our Controller
To send a response, we'll need to map the request to the right action. If the `resources` keyword was used, the route `GET /articles` will call the `#index` action.

We want the response to be a page rendering all the articles our blog currently has. To do that we can create the `#index` action in our controller, get all our articles and store it into an instance variable.
```ruby
# Inside `app/articles_controller.rb`
class TasksController < ApplicationController
  def index
    @articles = Article.all
  end 
end
```
Here's one thing to notice, Rails implicitly calls a render (and passes our instances variables) for a view with the same name of our action, so a call for `#index` in the articles controller will render the file `app/views/articles/index.html.erb`, remember "Convention over Configuration" now you're seeing this in action. So let's create that file.
```erb
<%# In `app/views/articles/index.html.erb` %>
<h1>Index</h1>
<%# Here we can use: `@articles` %> 
<% @articles.each do |article| %>
  <div>
    <h2><%= article.title %></h2>
    <p><%= article.body %></p>
  </div>
<% end %>
```

And that's it. That's pretty much how the MVC architecture works in Rails. 

Remember these series should only be used as a refresher, the way of really learning Rails is by reading the Guides. 

Don't forget to like, save and ask questions (I'll be answering everything I can, just remember I'm not an expert YET). Also, if you have experience with Rails, feel free to point out topics that I might be missing and suggestions you might have.