Routes / MVC

Routes、Model、View、Controller 的概念困擾很久,簡單來說:

MVC 是軟體設計的一種模式(software design pattern),可以參考Wiki

進入 MVC 世界之前,補了一些 Internet 與 Web 的運作邏輯,

Internet 與 Web

什麼是 internet?

  • Internet 是 Web 的基礎,換句話說, Web 是建構在 Internet 之上。

  • Internet 是電腦與電腦之間的連結

    圖片來源:MDN

  • Route 是當電腦間的連結關係複雜時候的一種連結管理

    圖片來源:MDN

  • network 是 Routes 規模變大,連結 Routes 間的連結管理

    圖片來源:MDN

  • ISP(Internet Service Provider) 是 network 間的連結管理

圖片來源:MDN

  • IP(Internet Protocol) 連結到 network 的識別,一連串數字組成 142.250.190.78,但我們連到網頁上不太可能會把一整串數字背出來,所以我們需要 domain namehttps://www.google.com.tw/

什麼是 Web?

Web 是介於客戶(client)與主機(server)之間的關係, client 會向 server 發送請求,server 會回應 client 的需求,網路世界的供需關係。

MDN 關於 Web 的描述很深刻

For now, let’s imagine that the web is a road. On one end of the road is the client, which is like your house. On the other end of the road is the server, which is a shop you want to buy something from.

Web

依照網路世界運作模式來看,可以解釋為什麼在 Ruby on Rails 的建立會依照Routes > Model > View > Controller這樣的順序進行

Routes

路徑是建立 client 與 server 之間橋樑。

Rails 的第一步:設定 Routes。

Routes 的設計是依照REST(Representational State Transfer)的設計風格
REST 翻成專有名詞反而有點難理解,表現層狀態轉移,白話文應該可以說:看網址就知道你要幹嘛,這個留到日後再慢慢補上,免得越陷越深。
回到思考 Routes 的過程,可以理解成把自己想像成使用者,怎樣的網址設計可以讓使用者與設計者一眼就可以知道想看到的內容和需要呈現的內容。
後續再設計 MVC 結構也許可以換一個角度評估:
進入頁面後,

期待看到的內容是什麼?

畫面的操作流程是什麼?

會期待網頁有什麼功能?

是購物型網站?

資訊瀏覽網站?

購物網站?

登入功能應該有哪些?

透過這樣的疑問句來找出需要建立的 Model 需要哪些內容 > View 畫面要怎麼呈現 > Controller 介於 DataBase 與 View 之間的橋樑

Model

Model 是用 Ruby 類別 (class)的方式表示 data,在 Model 透過 Active Record 和 database 拿到需要的資料。
建立 model 需要注意 model_name 的大小寫與單複數問題
這裡可以這樣記:因為 model 是一筆一筆的資料寫進資料庫

bin/rails generate model Article title:string body:text

意思是:用 rails 建立一個 Article 的 model,在這 model 裡面需要的資料結構,title 是 string,body 是 text

ActiveRecord

Active Record 是 MVC 裡面的 M,呈現資料與邏輯
Object Relational Mapping(ORM) system 是連結資料庫的管理架構。

再深入的解釋 Active Record:

  • 呈現 data 跟 model
  • model 之間的關聯性、階層
  • 驗證 Model 的資料格式
  • 用物件導向的方式來呈現資料結構
1
2
class User < ApplicationRecord
end

Database Migration

官方文件對於 Database Migration 的解釋是

Migrations are used to alter the structure of an application’s database. In Rails applications, migrations are written in Ruby so that they can be database-agnostic.

我的理解是:用 Ruby 表示的 database 的資料結構,更好理解。

1
2
3
4
5
6
7
8
9
10
11
12
class CreateResumes < ActiveRecord::Migration[6.1]
def change
create_table :resumes do |t|
t.string :title
t.text :content
t.string :status

t.timestamps
end

end
end

乍看之下,Migration 跟 ActiveRecord 好像有那麼一點像?
沒有他們不一樣!

Migration 是把 database 內的資料格式列出來,所以要調整 column 的項目,可以另外進行一些客製化調整
bin/rails generate migration AddPartNumberToProducts part_number:string

意思是:用 rails 建立一個 migration 檔案,在這檔案裡面需要再加上一個 part_number 的 column 到 products 的 model 中,他的 data type 是 string

1
2
3
4
5
class AddPartNumberToProducts < ActiveRecord::Migration[6.0]
def change
add_column :products, :part_number, :string
end
end

ActiveRecord 是定義資料間的關聯性與驗證資料。

最後在建立 Migration 後還要再將需要的 data type 寫進資料庫,
bin/rails db:migrate
有些人稱為具現化,
我覺得太抽象,
可能更像一種寫進資料庫前的防呆機制,在寫進去之前,要改都是有機會的,寫進去之後就是要在重新 generate 一個 migrate…

View

以 client 的角度而言,當 web 發送一個 request 後,Action Controller 負責與 database 要來的資料,執行 CRUD Action, Action View 會顯示資料的畫面。
View 中還有許多細節,留到接下來的實作紀錄在細細介紹,

Controller

controller 會從 router 那邊接收 request,依照 request 去找 model fetch 或 save data,再透過 view 產生畫面。
Controller 介於 models 和 views 中間,可以讓 model 的 data 可以透過 view 的畫面呈現給 client,也同時讓 client 可以上傳或是儲存 data 到 model 中。