Rails Basics - WeRecycle/RhodyCode GitHub Wiki

Basic web stuff

Http methods

Http is a how the client (browser) communicates with the server (rails). There are different Http methods that can be sent to the server. The main ones are:

  • GET
  • POST
  • PUT
  • DELETE

These methods are used to describe the request being made. In rails if a GET request is made to the route /projects it means you are asking for the products index page. However, a POST request to that same route (/projects) means you are creating a new project.

JSON

JSON is a data format used to transmit data between the client and server. An example JSON that could be used to create a new project (This would be sent with a HTTP POST request to the server):

{
  title: 'This is the title',
  description: 'This is the description',
  user_id: 1
}

Overview of how rails works

The main pieces of rails are the Database, the Router, the Controllers, the Models, and the Views

The Database

Rails handles the majority of interacting with the database, the only things you need to worry about are the migrations. Here is an example migration:

class CreateProjects < ActiveRecord::Migration[5.0]
  def change
    create_table :projects do |t|
      t.string :title #creates title column in table that is a string
      t.text :description #creates description column in table that is a text (like string but accepts longer inputs)
      t.integer :points #creates points column in table that is an integer

      t.timestamps #creates created_at and updated_at columns in table that are automatically handled by rails
    end
  end
end

This creates a table called projects that has title, description, points, created_at, and updated_at columns.

The Model

The model is the connection between the database and the rest of your application. It often doesn't need many methods and can be completely empty. This is also where you tell the application that one model has a relationship with another model, usually either has_many or belongs_to. Example model:

class Project < ApplicationRecord
  belongs_to :user #this assumes the Projects table has a user_id field
end

This allows you to do many cool things like:

  1. Project.all queries database and returns all projects
  2. Project.find(1) queries the database and returns project with id == 1
  3. Project.create title: 'The title', description: 'the description', user_id: 1 creates new project and saves it to the database

The Router

The router is the mapping between the routes (urls) and controller actions. A basic router config for projects would just be:

Rails.application.routes.draw do
  resources :projects
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

This creates the following routes (:id would be a number):

HTTP Method Path controller#action Named helper
GET /projects projects#index projects_path
POST /projects projects#create projects_path
GET /projects/new projects#new new_project_path
GET /projects/:id/edit projects#edit edit_project_path
GET /projects/:id projects#show project_path
PUT /projects/:id projects#update project_path
DELETE /projects/:id projects#destroy project_path

The View

Rails views are fairly basic. They are basic html with ruby syntax mixed in. The syntax to mix in ruby is:

<div>
  <% ruby_statement %> <!-- if it begins with <% then it doesn't return anything -->
  <%= ruby_statement %> <!-- if it begins with <%= then it returns a value -->
</div>

example projects index view:

<p id="notice"><%= notice %></p>

<h1>Projects</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Description</th>
      <th>Points</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @projects.each do |project| %>
      <tr>
        <td><%= project.title %></td>
        <td><%= project.description %></td>
        <td><%= project.points %></td>
        <td><%= link_to 'Show', project %></td>
        <td><%= link_to 'Edit', edit_project_path(project) %></td>
        <td><%= link_to 'Destroy', project, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Project', new_project_path %>

Each view corresponds to an action (see below) and is passed data using the controller.

The Controller

The Controller is what connects the Model to the View. It uses the model to either create, read, update, or destroy an object from the database. It then sends data to the view which is rendered and sent to the client. An example controller for projects:

class ProjectsController < ApplicationController

  # GET /projects
  # GET /projects.json
  def index
    @projects = Project.all
  end

  # GET /projects/1
  # GET /projects/1.json
  def show
    @project = Project.find(params[:id])
  end

  # GET /projects/new
  def new
    @project = Project.new
  end

  # GET /projects/1/edit
  def edit
    @project = Project.find(params[:id])
  end

  # POST /projects
  # POST /projects.json
  def create
    @project = Project.new(project_params)

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

  # PATCH/PUT /projects/1
  # PATCH/PUT /projects/1.json
  def update
    @project = Project.find(params[:id])
    respond_to do |format|
      if @project.update(project_params)
        format.html { redirect_to @project, notice: 'Project was successfully updated.' }
        format.json { render :show, status: :ok, location: @project }
      else
        format.html { render :edit }
        format.json { render json: @project.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /projects/1
  # DELETE /projects/1.json
  def destroy
    @project = Project.find(params[:id])
    @project.destroy
    respond_to do |format|
      format.html { redirect_to projects_url, notice: 'Project was successfully destroyed.' }
      format.json { head :no_content }
    end
  end
end

Each of these actions has a corresponding view. These views would go in a projects directory within the views directory.

The @ symbol in rails is used to define instance variables. In the case of controllers and views any instance variable that is defined within an action is passed to the corresponding view.

This means for the show action the project can be accessed within the view using @projects like this:

<h1><%= @project.title %></h1>

This would render a header tag containing the title of the project.

So the basic flow

  1. User navigates to /projects (GET request)
  2. Router checks routes and sees that a GET request to /projects means it should call the index action in the ProjectController.
  3. The show method within the ProjectController gets all Projects and saves it in the @projects instance variable
  4. Rails now knows to render the view/projects/show.index.erb view, with @project accessible from within.
  5. This html is then sent to the user.
⚠️ **GitHub.com Fallback** ⚠️