才华横溢 todo 教学案例
才华横溢 todo 教学案例 6
第1部分 新建专案
cd workspace
rails new todo
cd todo
rails s
atom .
git status
git add .
git commit -m "initial commit"
git remote add origin https://github.com/shenzhoudance/todo.git
git push -u origin master
git checkout -b todo_list
rails g scaffold todo_list title:string description:text
rake db:migrate
rails server
http://localhost:3000/todo_lists
config/routes.rb
root 'todo_lists#index'
http://localhost:3000/
rails g model todo_item content:string todo_list:references
rake db:migrate
config/routes.rb
---
resources :todo_lists do
resources :todo_items
end
---
app/models/todo_list.rb
---
has_many :todo_items
---
rake routes
rails g controller todo_items
class TodoItemsController < ApplicationController
def create
@todo_list = TodoList.find(params[:todo_list_id])
@todo_ltem = @todo_list.todo_items.create(params[:todo_item].permit(:content))
end
private
def set_todo_list
@todo_list = TodoList.find(params[:todo_list_id])
end
def todo_item_params
params[:todo_item].permit(:content)
end
end
class TodoItemsController < ApplicationController
before_action :set_todo_list
def create
@todo_item = @todo_list.todo_items.create(todo_item_params)
redirect_to @todo_list
end
private
def set_todo_list
@todo_list = TodoList.find(params[:todo_list_id])
end
def todo_item_params
params[:todo_item].permit(:content)
end
end
app/views/todo_items/_todo_item.html.erb
---
<p><%= todo_item.content %></p>
<%= link_to "Delete",todo_list_todo_item_path(@todo_list,todo_item.id),methed: :delete,data:{ confirm:"are you sure?"} %>
---
app/controllers/todo_items_controller.rb
---
class TodoItemsController < ApplicationController
before_action :set_todo_list
def create
@todo_item = @todo_list.todo_items.create(todo_item_params)
redirect_to @todo_list
end
def destory
@todo_item = @todo_list.todo_items.find(params[:id])
if @todo_item.destroy
flash[:success] = "todo list item was delete."
else
lash[:error] = "todo list item could not be delete."
end
redirect_to @todo_list
end
private
def set_todo_list
@todo_list = TodoList.find(params[:todo_list_id])
end
def todo_item_params
params[:todo_item].permit(:content)
end
end
---
git status
git add .
git commit -m "Add Todo Lists & Todo Items"
git push origin todo_list
git checkout -b add_completed_at
rails g migration add_completed_at_to_todo_items completed_at:datetime
rake db:migrate
config/routes.rb
---
Rails.application.routes.draw do
resources :todo_lists do
resources :todo_items do
member do
patch :complete
end
end
end
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root 'todo_lists#index'
end
rake routes
app/views/todo_items/_todo_item.html.erb
---
<p><%= todo_item.content %></p>
<%= link_to "Delete",todo_list_todo_item_path(@todo_list,todo_item.id),methed: :delete,data:{ confirm:"are you sure?"} %>
<%= link_to "mark as complete",complete_todo_list_todo_item_path(@todo_list,todo_item.id) ,method: :patch %>
app/controllers/todo_items_controller.rb
---
class TodoItemsController < ApplicationController
before_action :set_todo_list
before_action :set_todo_item, except:[:create]
def create
@todo_item = @todo_list.todo_items.create(todo_item_params)
redirect_to @todo_list
end
def destory
if @todo_item.destroy
flash[:success] = "todo list item was delete."
else
lash[:error] = "todo list item could not be delete."
end
redirect_to @todo_list
end
def complete
@todo_item.update_attribute(:completed_at,Time.now)
redirect_to @todo_list,notice:"todo item complete"
end
private
def set_todo_list
@todo_list = TodoList.find(params[:todo_list_id])
end
def set_todo_item
@todo_item = @todo_list.todo_items.find(params[:id])
end
def todo_item_params
params[:todo_item].permit(:content)
end
end
app/views/todo_items/_todo_item.html.erb
---
<div class="row clearfix">
<% if todo_item.completed? %>
<div class="complete">
<%= link_to "mark as complete",complete_todo_list_todo_item_path(@todo_list,todo_item.id) ,method: :patch %>
</div>
<div class="todo_item">
<p style="opacity: 0.4;"><strike><%= todo_item.content %></strike></p>
</div>
<div class="trash">
<%= link_to "Delete",todo_list_todo_item_path(@todo_list,todo_item.id),methed: :delete,data:{ confirm:"are you sure?"} %>
</div>
<% else %>
<div class="complete">
<%= link_to "mark as complete",complete_todo_list_todo_item_path(@todo_list,todo_item.id) ,method: :patch %>
</div>
<div class="todo_item">
<p><<%= todo_item.content %>></p>
</div>
<div class="trash">
<%= link_to "Delete",todo_list_todo_item_path(@todo_list,todo_item.id),methed: :delete,data:{ confirm:"are you sure?"} %>
</div>
<% end %>
</div>
app/models/todo_item.rb
---
class TodoItem < ApplicationRecord
belongs_to :todo_list
def completed?
!completed_at.blank?
end
end
git status
git add .
git commit -m "mark as complete ability"
git push origin add_completed_at
git checkout -b add_scss
app/assets/stylesheets/application.css.scss
---
$white_opaque: rgba(250, 250, 250, .3);
$dark: #1F7972;
* {
box-sizing: border-box;
}
html {
height: 100%;
}
body {
height: 100%;
background: -webkit-linear-gradient(40deg, #4CB8C4 10%, #EAECC6 100%);
background: -moz-linear-gradient(40deg, #4CB8C4 10%, #EAECC6 100%);
background: -ms-linear-gradient(40deg, #4CB8C4 10%, #EAECC6 100%);
background: -o-linear-gradient(40deg, #4CB8C4 10%, #EAECC6 100%);
background: linear-gradient(40deg, #4CB8C4 10%, #EAECC6 100%);
font-family: 'Lato', sans-serif;
}
.clearfix:before,
.clearfix:after {
content: " ";
display: table;
}
.clearfix:after {
clear: both;
}
#notice {
text-align: center;
font-size: 0.6em;
color: $dark;
font-weight: 100;
}
.container {
width: 50%;
max-width: 750px;
background: $white_opaque;
margin: 3em auto 0 auto;
border-radius: 7px;
-webkit-box-shadow: 0 0 4px 3px rgba(0,0,0,.3);
box-shadow: 0 0 4px 4px rgba(0,0,0,.03);
padding: 1em 0;
}
.todo_list_title {
text-align: center;
font-weight: 700;
font-size: 2.5rem;
text-transform: uppercase;
color: white;
margin: 0;
a {
text-decoration: none;
color: white;
transition: all .4s ease-in-out;
&:hover {
opacity: 0.4;
}
}
}
.todo_list_sub_title {
margin: 0 0 3em 0;
text-align: center;
font-size: 0.9em;
color: $dark;
font-weight: 100;
}
.index_row {
padding: 2em;
border-bottom: 1px solid rgba(250,250,250, .3);
.todo_list_sub_title {
margin-bottom: 0;
}
}
#todo_items_wrapper {
.row {
width: 100%;
border-top: 1px solid rgba(250,250,250, .3);
border-bottom: 1px solid rgba(250,250,250, .3);
.complete {
width: 10%;
float: left;
text-align: center;
border-right: 1px solid rgba(250,250,250, .3);
padding: 1em 0;
}
.todo_item {
width: 80%;
float: left;
p {
margin: 0;
padding: 1em;
color: $dark;
font-weight: 100;
}
}
.trash {
width: 10%;
float: left;
text-align: center;
border-left: 1px solid rgba(250,250,250, .3);
padding: 1em 0;
}
i {
color: white;
transition: all .4s ease-in-out;
&:hover {
color: $dark;
}
}
}
#form {
margin-top: 2em;
padding: 0 5%;
input[type="text"] {
width: 72%;
margin-right: 2%;
display: inline-block;
outline: none;
background: rgba(250,250,250,.4);
border: none;
height: 40px;
border-radius: 4px;
padding: 1em 2em;
}
input[type="submit"] {
background: rgba(250,250,250,.4);
outline: none;
border: none;
height: 40px;
border-radius: 4px;
width: 25%;
display: inline-block;
transition: all .4s ease-in-out;
cursor: pointer;
&:hover {
background: $dark;
}
}
::-webkit-input-placeholder { color: $dark; }
}
}
.links {
display: block;
margin: 1.5em auto 0 auto;
text-align: center;
font-size: 0.8em;
color: white;
a {
color: white;
}
}
.forms {
padding: 0 5%;
}
label {
color: $dark;
}
input[type="text"], textarea {
width: 100%;
margin: .5em 2% 1em 0;
display: inline-block;
outline: none;
background: rgba(250,250,250,.4);
border: none;
height: 40px;
border-radius: 4px;
padding: 1em 2em;
}
textarea {
height: 200px;
}
input[type="submit"] {
background: white;
outline: none;
border: none;
height: 40px;
border-radius: 4px;
width: 25%;
display: inline-block;
transition: all .4s ease-in-out;
cursor: pointer;
color: $dark;
&:hover {
background: $dark;
color: white;
}
}
::-webkit-input-placeholder { color: $dark; }
app/views/layouts/application.html.erb
---
<body>
<div class="container">
<%= yield %>
</div>
</body>
app/views/todo_lists/index.html.erb
---
<% @todo_lists.each do |todo_list| %>
<div class="index_row clearfix">
<h2 class="todo_list_title"><%= link_to todo_list.title, todo_list %></h2>
<p class="todo_list_sub_title"><%= todo_list.description %></p>
</div>
<% end %>
<div class="links">
<%= link_to "New Todo List", new_todo_list_path %>
</div>
app/views/layouts/application.html.erb
https://fonts.google.com/
https://fontawesome.com/how-to-use/svg-with-js
---
<head>
<title>才华横溢</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
<link href='http://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
</head>
app/views/todo_items/_todo_item.html.erb
---
<div class="complete">
<%= link_to complete_todo_list_todo_item_path(@todo_list, todo_item.id), method: :patch do %>
<i style="opacity: 0.4;" class="fa fa-check"></i>
<% end %>
</div>
<div class="row clearfix">
<% if todo_item.completed? %>
<div class="complete">
<%= link_to complete_todo_list_todo_item_path(@todo_list, todo_item.id), method: :patch do %>
<i style="opacity: 0.4;" class="fa fa-check"></i>
<% end %>
</div>
<div class="todo_item">
<p style="opacity: 0.4;"><strike><%= todo_item.content %></strike></p>
</div>
<div class="trash">
<%= link_to "Delete",todo_list_todo_item_path(@todo_list,todo_item.id),methed: :delete,data:{ confirm:"are you sure?"} %>
</div>
<% else %>
<div class="complete">
<%= link_to "mark as complete",complete_todo_list_todo_item_path(@todo_list,todo_item.id) ,method: :patch %>
</div>
<div class="todo_item">
<p><<%= todo_item.content %>></p>
</div>
<div class="trash">
<%= link_to "Delete",todo_list_todo_item_path(@todo_list,todo_item.id),methed: :delete,data:{ confirm:"are you sure?"} %>
</div>
<% end %>
</div>
---
<div class="row clearfix">
<% if todo_item.completed? %>
<div class="complete">
<%= link_to complete_todo_list_todo_item_path(@todo_list, todo_item.id), method: :patch do %>
<i style="opacity: 0.4;" class="fa fa-check"></i>
<% end %>
</div>
<div class="todo_item">
<p style="opacity: 0.4;"><strike><%= todo_item.content %></strike></p>
</div>
<div class="trash">
<%= link_to todo_list_todo_item_path(@todo_list, todo_item.id), method: :delete, data: { confirm: "Are you sure?" } do %>
<i class="fa fa-trash"></i>
<% end %>
</div>
<% else %>
<div class="complete">
<%= link_to complete_todo_list_todo_item_path(@todo_list, todo_item.id), method: :patch do %>
<i class="fa fa-check"></i>
<% end %>
</div>
<div class="todo_item">
<p><%= todo_item.content %></p>
</div>
<div class="trash">
<%= link_to todo_list_todo_item_path(@todo_list, todo_item.id), method: :delete, data: { confirm: "Are you sure?" } do %>
<i class="fa fa-trash"></i>
<% end %>
</div>
<% end %>
</div>
app/views/todo_lists/show.html.erb
---<p id="notice"><%= notice %></p>
<p>
<strong>Title:</strong>
<%= @todo_list.title %>
</p>
<p>
<strong>Description:</strong>
<%= @todo_list.description %>
</p>
<div id="todo_items_wrapper">
<%= render @todo_list.todo_items %>
<div id="form">
<%= render "todo_items/form" %>
</div>
<div>
<%= link_to 'Edit', edit_todo_list_path(@todo_list) %> |
<%= link_to 'Back', todo_lists_path %>
---
<p id="notice"><%= notice %></p>
<h2 class="todo_list_title"><%= @todo_list.title %></h2>
<p class="todo_list_sub_title"><%= @todo_list.description %></p>
<div id="todo_items_wrapper">
<%= render @todo_list.todo_items %>
<div id="form">
<%= render "todo_items/form" %>
</div>
</div>
<div class="links">
<%= link_to 'Edit', edit_todo_list_path(@todo_list) %> |
<%= link_to 'Delete', todo_list_path(@todo_list), method: :delete, data: { confirm: "Are you sure?" }
%> |
<%= link_to 'Back', todo_lists_path %>
</div>
app/views/todo_lists/new.html.erb
---
<h1>New Todo List</h1>
<%= render 'form', todo_list: @todo_list %>
<%= link_to 'Back', todo_lists_path %>
---
<h1 class="todo_list_title">New Todo List</h1>
<div class="forms">
<%= render 'form', todo_list: @todo_list %>
</div>
<div class="links">
<%= link_to 'Back', todo_lists_path %>
</div>
<h1>Editing Todo List</h1>
<%= render 'form', todo_list: @todo_list %>
<%= link_to 'Show', @todo_list %> |
<%= link_to 'Back', todo_lists_path %>
---
<h1 class="todo_list_title">Editing Todo List</h1>
<div class="forms">
<%= render 'form', todo_list: @todo_list %>
</div>
<div class="links">
<%= link_to 'Show', @todo_list %> |
<%= link_to 'Back', todo_lists_path %>
</div>
最后的效果图展示