So You Think You Can Rails
Published: 2020-11-10 21:21:08

When I began coding with Rails only 3 weeks ago, I could state with confidence that I only understood about 20 percent of the reading material. The firehose of information was opened to max, and I had about two weeks to understand it all before our code challenge. 

It was a lot of information, so I buckled down, read, and re-read the key READMEs, rewatched old lectures to the point that I found myself asking questions to my instructor from 4 days ago. In the end, I overcame, and passed! With this new albeit short feeling of triumph, I decided to write this post with some fundamental Rails commands to streamline your programming process.


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/52zko6ajuy4nkeub5fok.jpg)

### Basic MVC Architecture

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ksr7xbzwg9b3djqcvp0d.png)

Model View Controller or **MVC** is a software design pattern for developing web applications. 
* Model - Responsible for maintaining data.
* View - Presents all or some data to the User
* Controller - Responds to user input and performs interactions between models and views

### Create a new application

Install the Rails gem if you haven't done so before

```
$ gem install rails
```

Generate a new Rails app

```
$ rails new my-app 
```

Initialize the database

```
$ rake db:create
```

Start the Rails server

```
$ rails s
```

### Routes

Create a route that maps a URL to the controller action

```rb
# config/routes.rb
get 'welcome' => 'pages#home'
```

Shorthand for connecting a route to a controller/action
```rb
# config/routes.rb
get 'photos/show'

# The above is the same as: 
get 'photos/show', :to 'photos#show'
get 'photos/show' => 'photos#show'
```

Similarly, you can create all the RESTful routes for a resource by simply...

```rb
# config/routes.rb
resources :photos 
```

HTTP Verb | Path | Controller#Action | Used for
--------- | ---- | ----------------- | -------
GET | /photos | photos#index | display a list of all photos
GET | /photos_new | photos#new | return an HTML form for creating a new photo
POST | /photos | photos#create | create a new photo
GET | /photos/:id | photos#show | display a specific photo
GET | /photos/:id/edit | photos#edit | return an HTML form for editing a photo
PATCH/PUT | /photos/:id | photos#update | update a specific photo
DELETE | /photos/:id | photos#destroy | delete a specific photo

Create resources for specific actions... 

```rb
# config/routes.rb
resources :photos, only: [:index]
```

Create a route to a static view, without an action in the controller

```rb
# config/routes.rb
# If there's a file called 'about.html.erb' in 'app/views/photos', this file will be 
#   automatically rendered when you call localhost:3000/photos/about
get 'photos/about', to: 'photos#about'
```

Reference: http://guides.rubyonrails.org/routing.html

### Controllers

Generate a new controller 

**Attention:** Capitalize controller names and pluralize

```
$ rails g controller Photos
```

You can generate a new controller with default actions, routes and views

```
$ rails g controller Photos index show
```

Reference: http://guides.rubyonrails.org/action_controller_overview.html

### Models

Generate a model and create a migration for each table

**Attention:** Capitalize model names and singular

```
$ rails g model Photo
```

Generate a model and create a migration with table columns

```
$ rails g model Photo location:string description:text
```

The migration automatically created for the above command: 

```rb
class CreatePhotos < ActiveRecord::Migration
  def change
    create_table :photos do |t|
      t.string :location
      t.text :description
 
      t.timestamps null: false
    end
  end
end
```

Reference: http://guides.rubyonrails.org/active_model_basics.html

### Migrations

Migration Data Types

* `:boolean`
* `:date`
* `:datetime`
* `:decimal`
* `:float`
* `:integer`
* `:primary_key`
* `:references`
* `:string`
* `:text`
* `:time`
* `:timestamp`

### Scaffolding

Scaffolding is great for prototypes but **don't** rely too heavily on it. Here's a good explanation on why: http://stackoverflow.com/a/25140503

```
$ rails g scaffold Photo location:string description:text
$ rake db:migrate
```

### Rake

View all the routes in an application

```
$ rake routes
```

Seed the database with sample data from `db/seeds.rb`

```
$ rake db:seed
```

Run any pending migrations

```
$ rake db:migrate
```

Rollback the last migration performed

**ATTENTION:** Keep in mind that this command is destructive and you could lose your data. Make sure you run any pending migrations and re-seed after making the appropriate changes.

```
$ rake db:rollback
```
...will rollback your migrations **one** step.

```
$ rake db:rollback STEP=n
```
...will rollback your migrations **n** number of steps.

### Path Helpers 

Creating a path helper for a route

```rb
# Creating a path helper for a route
get '/photos/:id', to: 'photos#show', as: 'photo'
```

```rb
# app/controllers/photos_controller.rb
def show
@photo = Photo.find(params[:id])
end
```

```rb
# View for the action
<%= link_to 'Photo View Page', photo_path(@photo) %>
```

Once again, path helpers are automatically created when specifying a **resource** in `config/routes.rb`

```rb
# config/routes.rb
resources :photos
```

For example,  let's look at all the RESTful routes for _photos_

HTTP Verb | Path | Controller#Action | Named Helper
--------- | ---- | ----------------- | ------------
GET | /photos | photos#index | photos_path
GET | /photos/new | photos#new | new_photo_path
POST | /photos | photos#create | photos_path
GET | /photos/:id | photos#show | photo_path(:id)
GET | /photos/:id/edit | photos#edit | edit_photo_path(:id)
PATCH/PUT | /photos/:id |	photos#update | photo_path(:id)
DELETE | /photos/:id | photos#destroy | photo_path(:id)

### Form Helpers

Connect a form to a model for creating or updating a resource.

**Use this method if you're using strong params to protect against mass assignment**.
Some helpful documentation on strong params and mass assignment: https://ropesec.com/articles/mass-assignment/

```rb
# app/controllers/photos_controller.rb
def new
  @photo = Photo.new
end
```

```rb
# app/controllers/photos_controller.rb
def create
  @photo = Photo.new(params.require(:photo).permit(:description, :location)
Photo.save
redirect_to photo_path(@photo)
end
```

```rb
# ERB view
<%= form_for @photo do |f| %>
  <%= f.text_field :location %>
  <%= f.text_area :description, size: "60x12" %>
  <%= f.submit "Submit" %>
<% end %>
```

And there you have it! Use this guide to help you understand the different rails commands to help you create your MVC along with RESTful routes for your Models. 

References: [http://guides.rubyonrails.org/form_helpers.html]
[http://www.pragtob.info/rails-beginner-cheatsheet/]