第四課:網頁程式簡介、Rails 入門
作業卡關是常態,不要輕易放棄
請花時間練習英文,對你絕對沒有壞處
1. 資源 (resource) + 方法 (method)
2. 無狀態性通訊 (Stateless protocol)
為了要和伺服器溝通,HTTP 制定了九種動詞,用於支援 CRUD 的操作:
- GET (讀取)
- POST (新增)
- PATCH (部分更新)
- PUT (完全更新)
- DELETE (刪除)
所以搭配上 url 後,就可以對資料進行操作了:
- GET /users
- POST /users
- PATCH /user/1
- PUT /user/1
- DELETE /user/1
1. Application Programming Interface
(應用編程介面)
2. 給不同程式互相溝通用的介面
DHH 開發於 2005 年
MVC 架構
Convention over Configuration (COC)
Don't Repeat Yourself (DRY)
敏捷開發
應用程式設計架構
最早源自 smalltalk 語言的概念
簡化專案結構、易於分工以及維護
<?php
$db = mysql_connect("localhost", "root", "password");
mysql_query("SET NAMES 'utf8'");
mysql_select_db($SERVER['db']);
?>
<html>
<?php
$sql="select * from news where Class='1' or Class='3' order by CTDate desc limit 0,5";
$result= mysql_query($sql);
while ( $arr=mysql_fetch_array($result) ) {
echo <<<NEWSEND
<div class="box">
<span class="box-title-1"> <b>【$arr[Title]】</b> $arr[CTDate] </span>
<div class="box-content">
$arr[Text]
</div>
</div>
NEWSEND;
}
?>
</html><?php
$db = mysql_connect("localhost", "root", "password");
mysql_query("SET NAMES 'utf8'");
mysql_select_db($SERVER['db']);
?>
<html>
<?php
$sql="select * from news where Class='1' or Class='3' order by CTDate desc limit 0,5";
$result= mysql_query($sql);
while ( $arr=mysql_fetch_array($result) ) {
echo <<<NEWSEND
<div class="box">
<span class="box-title-1"> <b>【$arr[Title]】</b> $arr[CTDate] </span>
<div class="box-content">
$arr[Text]
</div>
</div>
NEWSEND;
}
?>
</html>
早期包山包海的網頁...
1. Model 封裝資料與商業邏輯,與資料庫裡的資料表對應
2. View 處理使用者介面,顯示及編輯表單,可內嵌Ruby語法
3. Controller 負責將資料送進送出Model,處理從外界 (也就是瀏覽器) 來的HTTP Request請求,與Model互動後輸出View (也就是HTML)
1. 每一個自稱是 MVC framework 對 MVC 的定義不一定一樣, 因為大家都把 MVC 再定義了
2. 最初 Smalltalk 的 MVC 是指 Model 改變後需要以 Obesrver Pattern 去主動告知 View 去做出對應的更新,但是在 HTTP 的世界裡,我們很難這樣做,而是由 controller 回應給 View
3. 近年越來越流行 frontend javascript framework,後端 framework 變成單純回傳 json / xml 的 API server。 Presentaion layout 和 backend 就變得越來越沒關係了 ,
1. 瀏覽器發出HTTP request請求給Rails
2. 路由(Routing)根據規則決定派往哪一個Controller 的 Action
3. 負責處理的 Controller Action 操作 Model 資料
4. Model 存取資料庫或資料處理
5. Controller Action 將得到的資料餵給View樣板
6. 回傳最後的 HTML 成品給瀏覽器
# 使用 scaffold 指令
$rails new dinbento
$git init
$git add .
$git commit -m "first commit"
$rails g scaffold order name:string phone:string description:text
$rake db:migrate
$rails server
$git diff
Rails.application.routes.draw do
resources :orders
end
config/routes.rb 是一個 Rails 專案管理路由以及相對應 Controller Action 的檔案,Rails 專案的路由都是在這裡設定
class OrdersController < ApplicationController
before_action :set_order, only: [:show, :edit, :update, :destroy]
# GET /orders
# GET /orders.json
def index
@orders = Order.all
end
# GET /orders/1
# GET /orders/1.json
def show
end
# GET /orders/new
def new
@order = Order.new
end
# GET /orders/1/edit
def edit
end
# POST /orders
# POST /orders.json
def create
@order = Order.new(order_params)
respond_to do |format|
if @order.save
format.html { redirect_to @order, notice: 'Order was successfully created.' }
format.json { render :show, status: :created, location: @order }
else
format.html { render :new }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /orders/1
# PATCH/PUT /orders/1.json
def update
respond_to do |format|
if @order.update(order_params)
format.html { redirect_to @order, notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: @order }
else
format.html { render :edit }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
@order.destroy
respond_to do |format|
format.html { redirect_to orders_url, notice: 'Order was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
@order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:name, :phone, :description)
end
end
Controller 主要的功能:
1. 收集 request 的資訊,例如 使用者傳進來的參數
2. 操作 Model 來做資料的處理
3. 回傳 response 結果
class Order < ActiveRecord::Base
end
和資料庫的資料表相對應的抽象類別,和其他資料表的關聯、行為、商業邏輯等都是在這裡定義或處理
<p id="notice"><%= notice %></p>
<h1>Listing Orders</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
<th>Description</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @orders.each do |order| %>
<tr>
<td><%= order.name %></td>
<td><%= order.phone %></td>
<td><%= order.description %></td>
<td><%= link_to 'Show', order %></td>
<td><%= link_to 'Edit', edit_order_path(order) %></td>
<td><%= link_to 'Destroy', order, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Order', new_order_path %>
Controller 層面 - ActionPack::ActionController
View 層面 - ActionPack::ActionView
Model 層面 - ActiveRecord
$rails new my_app_name
建立新專案
$bundle install
安裝執行這個專案需要的 gem:
Gem 依存性(dependencies)管理工具
會根據 Gemfile 的設定自動下載及安裝 Gem 套件
在團隊開發時,維持開發者之間套件版本的一致性
config/database.yml
config/routes.rb
Gemfile
Rails 專案與 database 連結的設定檔
development 是用於開發時的設定
test 是用於執行自動測試時的設定
production 是用於正式環境上的設定
設定 URL 的檔案
設定一個 Rails 專案的 API (應用程序介面)
可以透過以下網址查詢:http://localhost:3000/rails/info/routes
也可在 terminal 裡輸入 rake routes 查詢
宣告在這個 Rails 專案中使用的 gem ( Ruby 套件)
bundler 會依據 gemfile 安裝該專案需要的套件
每次執行 bundle 後會產生 Gemfile.lock
Gemfile.lock 會詳細列出所有 gem 的版本
*不要修改 Gemfile.lock
Ruby 的 ORM (對映射關聯式資料與物件資料)
簡單來說,就是把資料表物件化,讓開發者不須使用 SQL 語法,直接用熟悉的 Ruby 於法操作資料
更簡單的說,它就是 SQL 語言與 Ruby 語言的翻譯官
從物件導向的角度來對映 SQL 資料庫
一個資料表對是應到類別 (Class)
資料表的每一筆資料則是對應到物件 (Object)
CREATE - 新增資料
READ - 讀取資料
UPDATE - 編輯資料
DELETE - 刪除資料
# 建立一筆 Order 資料
Order.create(name: "Bob", phone: "88888888888", description: "hamburger")
# 尋找這筆資料
Order.find(1)
# 更新這筆資料
Order.find(1).update(description: "sandwich")
# 刪除這筆資料
Order.find(1).destroy
資料操作方式
對應的 ActiveRecord 方法
類似 irb,不過只屬於一個專案的環境
可在裡面測試 ActiveRecord
$rails console
或
$rails c
OOP Rock Paper Scisscors
Quiz 1 & 2