Skip to content

Instantly share code, notes, and snippets.

@jendiamond
Last active March 17, 2017 04:11
Show Gist options
  • Select an option

  • Save jendiamond/5776c47378566baabdaa7f69cd618708 to your computer and use it in GitHub Desktop.

Select an option

Save jendiamond/5776c47378566baabdaa7f69cd618708 to your computer and use it in GitHub Desktop.

WEBSITE | GITHUB | TUTORIAL

READING


rails new to-do-today --database=postgresql

rake db:create


config/routes.rb

config/controllers/_controller.rb

app/views/.html.erb

app/models/.rb

Gemfile


Build the Home Page

Add routes

config/routes.rb

Rails.application.routes.draw do
  root 'application#hello'
end

Add the Home Page to the ApplicationController

config/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  
  def hello
    render plain: "Hello World"
  end
  
end

Change to add Page Controller

Add routes

config/routes.rb

Rails.application.routes.draw do
  root 'page#hello'
end

Add the Hello action to the PagesController

config/controllers/page_controller.rb

class PageController < ActionController
  
  def hello
  end
  
end

Create a Pages directory in views called pages. In that directory create a home page html

app/views/pages/hello.html.erb

<h1>Hello</h1>

Add routes to About and Help Pages

config/routes.rb

Rails.application.routes.draw do
  root 'page#hello'
  get '/help', 'pages#help'
  get '/about', 'pages#about'
end

Add the About and Help actions to the PagesController

config/controllers/page_controller.rb

class PageController < ActionController
  
  def hello
  end
  
  def help
  end
  
  def about
  end

end

Create a Help page

app/views/pages/help.html.erb

<h1>Help</h1>

Create an About page

app/views/pages/about.html.erb

<h1>About</h1>

Create a Table

Controller name - todos_controller.rb class TodosController
Model name - todo.rb class Todo
Table name - todos table

Create a table called Todos

$rails g migration create_todos

db/migrate/20170310025641_create_todos.rb

class CreateTodos < ActiveRecord::Migration[5.0]
  def change
    create_table :todos do |t|
    end
  end
end

Add fields to this table

$rails g migration create_todos

db/migrate/20170310025641_create_todos.rb

class CreateTodos < ActiveRecord::Migration[5.0]
  def change
    create_table :todos do |t|
      t.string :name
      t.text :description
    end
  end
end

Run the Migration

$rake db:migrate


Play with Rails Console

Create a Todo model

app/models/todo.rb

class Todo < ApplicationRecord

end

===

Run $ rails console

Todo.all  
  Todo Load (1.7ms)  SELECT "todos".* FROM "todos"
 => #<ActiveRecord::Relation []>

Create a new Todo object

lunch = Todo.new(name: "lunch", description: "I am going to have a keto burger for lunch")
 => #<Todo id: nil, name: "lunch", description: "I am going to have a keto burger for lunch"> 

primary key - A primary key is a field in a table which uniquely identifies each row/record in a database table. Primary keys must contain unique values. A primary key column cannot have NULL values.

Save the lunch object

lunch.save
   (1.0ms)  BEGIN
  SQL (5.6ms)  INSERT INTO "todos" ("name", "description") VALUES ($1, $2) RETURNING "id"  [["name", "lunch"], ["description", "I am going to have a keto burger for lunch"]]
   (1.0ms)  COMMIT
 => true 

Use create to make some more objects

`Todo.create(name:'', description:'')`
Todo.create(name:'Hike', description:'Griffith Park Carousel Hike')
   (1.8ms)  BEGIN
  SQL (0.5ms)  INSERT INTO "todos" ("name", "description") VALUES ($1, $2) RETURNING "id"  [["name", "Hike"], ["description", "Griffith Park Carousel Hike"]]
   (0.9ms)  COMMIT

Todo.create(name:'Study', description:'Udemy Rails 5')
   (2.4ms)  BEGIN
  SQL (0.1ms)  INSERT INTO "todos" ("name", "description") VALUES ($1, $2) RETURNING "id"  [["name", "Study"], ["description", "Udemy Rails 5"]]
   (1.3ms)  COMMIT
 => #<Todo id: 2, name: "Study", description: "Udemy Rails 5"> 

Find a particular object

todo2 = Todo.find(2)
  Todo Load (0.6ms)  SELECT  "todos".* FROM "todos" WHERE "todos"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
 => #<Todo id: 2, name: "Study", description: "Udemy Rails 5"> 
 
todo2.description
 => "Udemy Rails 5" 

Update a particular object

todo2 = Todo.find(2)
  Todo Load (0.6ms)  SELECT  "todos".* FROM "todos" WHERE "todos"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
 => #<Todo id: 2, name: "Study", description: "Udemy Rails 5"> 
 
todo2.description
 => "Udemy Rails 5"

todo2.description = "Udemy - Pro Ruby on Rails - Rails 5"
 => "Udemy - Pro Ruby on Rails - Rails 5" 
 
> todo2.save
   (0.8ms)  BEGIN
  SQL (1.1ms)  UPDATE "todos" SET "description" = $1 WHERE "todos"."id" = $2  [["description", "Udemy - Pro Ruby on Rails - Rails 5"], ["id", 2]]
   (1.1ms)  COMMIT
 => true 

Delete a particular object

> Todo.all
  Todo Load (1.8ms)  SELECT "todos".* FROM "todos"
 => #<ActiveRecord::Relation [#<Todo id: 1, name: "lunch", description: "I am going to have a keto burger for lunch">, #<Todo id: 3, name: "Hike", description: "carousel hike">, #<Todo id: 4, name: "", description: "">, #<Todo id: 2, name: "Udemy", description: "Udemy - Pro Ruby on Rails - Rails 5">]> 
2.3.0 :017 > Todo.all
  Todo Load (0.1ms)  SELECT "todos".* FROM "todos"
 => #<ActiveRecord::Relation [#<Todo id: 1, name: "lunch", description: "I am going to have a keto burger for lunch">, #<Todo id: 3, name: "Hike", description: "carousel hike">, #<Todo id: 4, name: "", description: "">, #<Todo id: 2, name: "Udemy", description: "Udemy - Pro Ruby on Rails - Rails 5">]> 
 
> Todo.last
  Todo Load (0.8ms)  SELECT  "todos".* FROM "todos" ORDER BY "todos"."id" DESC LIMIT $1  [["LIMIT", 1]]
 => #<Todo id: 4, name: "", description: ""> 
 
> todo4 = Todo.last
  Todo Load (0.9ms)  SELECT  "todos".* FROM "todos" ORDER BY "todos"."id" DESC LIMIT $1  [["LIMIT", 1]]
 => #<Todo id: 4, name: "", description: ""> 
 
> todo4.destroy
   (0.1ms)  BEGIN
  SQL (0.9ms)  DELETE FROM "todos" WHERE "todos"."id" = $1  [["id", 4]]
   (1.1ms)  COMMIT
 => #<Todo id: 4, name: "", description: ""> 
 
> Todo.all
  Todo Load (2.4ms)  SELECT "todos".* FROM "todos"
 => #<ActiveRecord::Relation [#<Todo id: 1, name: "lunch", description: "I am going to have a keto burger for lunch">, #<Todo id: 3, name: "Hike", description: "carousel hike">, #<Todo id: 2, name: "Udemy", description: "Udemy - Pro Ruby on Rails - Rails 5">]> 

Rails provides you getters and setters for the attributes (columns):

some_todo.description = "this is a new description"


Reading:

https://gist.github.com/jendiamond/2e2a8fe9db2d455144579bf8770c7db0

Write out the routes

Read the ruby on rails guides on routes

  • what routes are generated by resources?

  • Create the grid for resources :todos like it shows in the guides for resources :photos and paste an image of it to the Q & A as your assignment

  • Read about 1-to-many associations -> this is done in rails by the has_many and belongs_to association


Frontend interface

class TodosController < ApplicationController

  def new
  @todo = Todo.new
  end

end

Add the form to create a new todo item

app/views/todos/new.html.erb

<h1>Create a new Todo</h1>

<%= form_for @todo do |f| %>
  <p>
    <%= f.label :name %>
    <%= f.text_field :name %>
  <p>

  <p>
    <%= f.label :description %><br/>
    <%= f.text_field :description %>
  <p>

  <p>
    <%= f.submit %>
  <p>
<% end %>

READ ABOUT FORM HELPERS http://guides.rubyonrails.org/form_helpers.html

White list the parameters name and description

app/controllers/todos_controller.rb

class TodosController < ApplicationController

  def new
    @todo = Todo.new
  end

  def create
    @todo = Todo.new(todo_params)
  end

  private

  def todo_params
    params.require(:todo).permit(:name, :description)
  end

end

Add Validations for the parameters

app/models/todo.rb

class Todo < ApplicationRecord
  validates :name, presence: true
  validates :description, presence: true
end

Add Error Messages

app/views/todos/new.html.erb

Create a new Todo

<% if @todo.errors.any? %>

The following errors prevented your new todo item from being saved:

    <% @todo.errors.full_messages.each do |err| %>
  • <%= err %>
  • <% end %>
<% end %>

<%= form_for @todo do |f| %>

<%= f.label :name %> <%= f.text_field :name %>

<%= f.label :description %>
<%= f.text_field :description %>

<%= f.submit %>

<% end %> ```

Style the errors

 *= require_tree .
 *= require_self
 */
.error_messages {
  color: #a91616;
  border: #a8a8a8 solid 1px;
  width: 30%;
  padding: 5px;
  background-color: #ededed;
}

Ruby on Rails 5.0.2
Class
ActionDispatch::Flash < Object
actionpack/lib/action_dispatch/middleware/flash.rb

The flash provides a way to pass temporary primitive-types (String, Array, Hash) between actions. Anything you place in the flash will be exposed to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create action that sets flash[:notice] = "Post successfully created" before redirecting to a display action that can then expose the flash to its template. Actually, that exposure is automatically done.

The message will be gone by the time the next action has been performed.


Add Flash messages that show throughout the app

app/views/layouts/application.rb

<!DOCTYPE html>
<html>
  <head>
    <title>ToDoToday</title>
    <%= csrf_meta_tags %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <% flash.each do |name, msg| %>
      <ul>
        <li><%= msg %></li>
      </ul>
    <% end %>

    <%= yield %>
  </body>
</html>

Add the Show Action

app/controllers/todos_controller.rb

class TodosController < ApplicationController

  def new
    @todo = Todo.new
  end

  def create
    @todo = Todo.new(todo_params)
    if @todo.save
      flash[:notice] = "Your todo item was created sucessfully. :)"
      redirect_to todo_path(@todo)
    else
      render 'new'
    end
  end

  def show
    @todo = Todo.find(params[:id])
  end

  private

  def todo_params
    params.require(:todo).permit(:name, :description)
  end

end

Add Show View

app/views/todos/show.html.erb

<h1>Show TODO</h1>
<p><b>Name:</b> <%= @todo.name %></p>
<p><b>Description:</b> <%= @todo.description %></p>

Add the Edit/Update Actions

app/controllers/todos_controller.rb

class TodosController < ApplicationController

  def new
    @todo = Todo.new
  end

  def create
    @todo = Todo.new(todo_params)
    if @todo.save
      flash[:notice] = "Your todo item was created sucessfully. :)"
      redirect_to todo_path(@todo)
    else
      render 'new'
    end
  end

  def show
    @todo = Todo.find(params[:id])
  end

  def edit
    @todo = Todo.find(params[:id])
  end

  def update
    @todo = Todo.find(params[:id])
    if @todo.update
      flash[:notice] = "Your todo item was sucessfully edited. :)"
      redirect_to todo_path(@todo)
    else
      render 'edit'
    end
  end

  private

  def todo_params
    params.require(:todo).permit(:name, :description)
  end

end

Add the Edit View

app/views/todos/show.html.erb

<h1>Edit you Todo Item</h1>

<div class='error_messages'>
  <% if @todo.errors.any? %>
    <h3>The following errors prevented your new todo item from being saved:</h3>
    <ul>
      <% @todo.errors.full_messages.each do |err| %>
        <li><%= err %></li>
      <% end %>
    </ul>
  <% end %>
</div>

<%= form_for @todo do |f| %>
  <p>
    <%= f.label :name %>
    <%= f.text_field :name %>
  <p>

  <p>
    <%= f.label :description %><br/>
    <%= f.text_field :description %>
  <p>

  <p>
    <%= f.submit %>
  <p>
<% end %>

Add the Index Action

app/controllers/todos_controller.rb

class TodosController < ApplicationController

  def index
    @todos = Todo.all
  end

  def new
    @todo = Todo.new
  end

  def create
    @todo = Todo.new(todo_params)
    if @todo.save
      flash[:notice] = "Your todo item was created sucessfully. :)"
      redirect_to todo_path(@todo)
    else
      render 'new'
    end
  end

  def show
    @todo = Todo.find(params[:id])
  end

  def edit
    @todo = Todo.find(params[:id])
  end

  def update
    @todo = Todo.find(params[:id])
    if @todo.update
      flash[:notice] = "Your todo item was sucessfully edited. :)"
      redirect_to todo_path(@todo)
    else
      render 'edit'
    end
  end

  private

  def todo_params
    params.require(:todo).permit(:name, :description)
  end

end

Add the Index Page View and Links to Edit and Show

app/views/todos/index.html.erb

<h1>All your Todos</h1>
<p><%= link_to "Create a New Todo Item", new_todo_path %></p>
<table>
  <tr>
    <th>NAME</th>
    <th>DESCRIPTION</th>
  </tr>
  <% @todos.each do |todo| %>
    <tr>
      <td><%= todo.name %></td>
      <td><%= todo.description %></td>
      <td><%= link_to 'Edit', edit_todo_path(todo) %></td>
      <td><%= link_to 'Show', todo_path(todo) %></td>
    </tr>
  <% end %>
</table>

Add the Delete Action

app/controllers/todos_controller.rb

class TodosController < ApplicationController

  def index
    @todos = Todo.all
  end

  def new
    @todo = Todo.new
  end

  def create
    @todo = Todo.new(todo_params)
    if @todo.save
      flash[:notice] = "Your todo item was created sucessfully. :)"
      redirect_to todo_path(@todo)
    else
      render 'new'
    end
  end

  def show
    @todo = Todo.find(params[:id])
  end

  def edit
    @todo = Todo.find(params[:id])
  end

  def update
    @todo = Todo.find(params[:id])
    if @todo.update(todo_params)
      flash[:notice] = "Your todo item was sucessfully edited. :)"
      redirect_to todo_path(@todo)
    else
      render 'edit'
    end
  end

  def destroy
    @todo = Todo.find(params[:id])
    @todo.destroy
    flash[:notice] = "Todo was deleted"
    redirect_to todos_path
  end

  private

  def todo_params
    params.require(:todo).permit(:name, :description)
  end

end

Add the Delete Llink to the Index Page

app/views/todos/index.html.erb

<h1>All your Todos</h1>
<p><%= link_to "Create a New Todo Item", new_todo_path %></p>
<table>
  <tr>
    <th>NAME</th>
    <th>DESCRIPTION</th>
  </tr>
  <% @todos.each do |todo| %>
    <tr>
      <td><%= todo.name %></td>
      <td><%= todo.description %></td>
      <td><%= link_to 'Edit', edit_todo_path(todo) %></td>
      <td><%= link_to 'Show', todo_path(todo) %></td>
      <td><%= link_to 'Delete', todo_path(todo), method: :delete, data: {confirm: 'Are you sure?'} %></td>
    </tr>
  <% end %>
</table>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment