2023-1-31 更新
本教材的主要目的,是要開發一套「任務管理系統」。這個系統需要做到的事情有:
- 任務功能
- 可新增自己的任務。
- 使用者登入後,只能看見自己建立的任務。
- 可設定任務的開始及結束時間。
- 可設定任務的優先順序(高、中、低)。
- 可設定任務目前的狀態(待處理、進行中、已完成)。
- 可依狀態篩選任務。
- 可以任務的標題、內容進行搜尋。
- 可為任務加上分類標籤。
- 任務列表,並可依優先順序、開始時間及結束時間等進行排序。
滿足以上需求之後,還會需要如下的管理機制:
- 使用者的管理功能
- 預設需要支援各種瀏覽器較新的版本。
請以下列程式語言、網站開發框架及資料庫系統進行開發:
- Ruby 3
- Ruby on Rails 6 或 7
- PostgreSQL
伺服器建議使用以下平台(不限定):
- Heroku
- Fly.io
- AWS
- GCP
※ 本教材對效能、資安沒有特別的要求,但仍需要有一定的品質。網站效能太差的話,會被要求改善。
完成本教材後,我們會認為你已經具備以下能力:
- 可以實做基本的 Rails 網站以及做簡單的佈署。
- 對於已經上線的 Rails 專案,能夠進行功能的追加和資料維護。
- 知道如何在 GitHub 發 PR、merge 等協作流程,以及必須的 Git 指令:
- 能將 commit 切成適度的大小。
- 能寫出適合的 PR 說明。
- 能針對 code review 進行修正。
- 遇到問題時,能夠適時以口頭或線上工具向相關人員(在本例中為導師)求救。
- Git: https://gitbook.tw/
- Rails: https://railsbook.tw/
- 以 gem 指令安裝 Rails
- 安裝最新版本的 Rails(至少 6.0 以上)
- 以
rails -v
指令來確認 Rails 的版本
- 在你使用的作業系統安裝資料庫系統軟體
- 在你的作業系統環境中安裝 Git。
- 以
git config
指令設定 user name 和 email。
- 以
- 請考慮專案名稱(也等於 Repository 名稱)。
- 建立 Repository
- 如果沒有帳號的話,先申請一個 GitHub 帳號。
- 接著建立空白的 Repository。
- 使用
rails new
指令,建立 Rails 應用程式最低限度的樣板和檔案。 - 為了方便之後開發時可以參考,請在
rails new
產生的專案目錄下建立docs
資料夾,並將本教程文件 commit 進去 - 將成品 push 到 GitHub。
- 將使用的 Ruby 版號寫進
Gemfile
(也請確認 Rails 版號是否有標明)。
- 開始進行設計之前,先和導師一起討論對最終成品的預想。建議在紙上畫 prototype。
- 請參照網站需求,開始想需要怎樣的資料結構
- 需要哪些 model (或資料表)?
- 資料表會需要哪些欄位?
- 有想法之後,將 model 的關係圖手繪出來
- 完成後將關係圖拍照存檔,放進專案裡。
- 把 table schema 寫到
README.md
(model 名稱、欄位名稱、資料形態)
※ 在這個階段,model 關係圖不需要是完全正確的。以現在所能預想的範圍來規劃就好(做到後面的步驟,發現需要修改時再來調整的概念)
- 建立新的
topic
分支。- 之後都在
topic
分支上開發並進行 Commit。
- 之後都在
- 安裝 Bundler。
- 在
Gemfile
安裝資料庫相對應套件。 - 設定
database.yml
。 - 使用
rails db:create
指令建立資料庫。 - 使用
rails db
指令確認有正確連接資料庫。 - 在 GitHub 上建立 PR(Pull Request)並請導師 review。
- 必要時,請在 PR 上標柱 WIP(Work In Progress)。
- PR 收到兩個 LGTM(Looks Good To Me)後就可以合併回
main
分支。
開始來做管理任務所需要的 CRUD。一開始先簡單做,只要能記錄名字和任務內容即可。
- 使用
rails generate
指令建立 CRUD 所需的 model。 - 撰寫 migration 並以此建立資料表。
- 非常重要:migration 要確定能安全回到上一步的狀態!請養成以
redo
確認的習慣。
- 非常重要:migration 要確定能安全回到上一步的狀態!請養成以
- 執行
rails c
指令,透過 model 確認有正確連接資料庫。- 試著直接在 console 環境建立資料。
- 完成後,在 GitHub 上發 PR 並請導師 review。
- 製作任務的列表、新增、檢視以及修改頁面。
- 使用
rails generate
指令建立 Controller。- 請和導師討論要用哪一種 template engine(ERB / Slim / Haml..etc)。
- 實做 Controller 和 View 必要的部分。
- 完成新增、修改、刪除之後需要在畫面上顯示的 Flash 訊息。
- 使用
- 修改
routes.rb
,讓http://localhost:3000/
會顯示任務的列表頁面。 - 在 GitHub 上發 PR 並請導師 review。
- 如果覺得 PR 內容過於龐大,就需要開始考慮分割成多個 PR。
- 寫 spec 的事前準備
- 準備
spec/spec_helper.rb
、spec/rails_helper.rb
。
- 準備
- 針對任務的功能來寫 feature spec。
- 導入 Travis CI 或 GitHub Actions 之類的 CI 工具,每次 Push 後自動執行 Spec。
- 太難的話可以請導師幫忙設定。
- 利用 Rails 的 i18n 功能,將 View / Controller / Model 中的語言部份共用化。
- 將系統的時區設為台灣(台北)
- 資料預設是以 id 進行排序,請試著讓它以建立時間排序。
- 完成後,撰寫 feature spec。
- 開始設定資料驗證
- 思考需要在哪個欄位上加入驗證。
- 與之配合的 DB 限制,請寫成 migration。
- 使用
rails generate
指令產生 migration file。
- 在頁面上加入驗證的錯誤訊息。
- 撰寫對應的 Model 測試。
- 在 GitHub 上發 PR 並請導師 review。
目的:將 main
分支上的簡易任務管理系統推上線
- 試著將網站佈署到雲端平台上。
- 檢視佈署完成的網站。
- 接下來就會在這裡建立任務並繼續開發。
- 今後,每個步驟完成後,就繼續將成品推上雲端平台。
- 將佈署的方法寫進
README.md
- 也將使用的 framework 版號等資料記下來
- 任務可設定結束時間。
- 列表頁可以結束時間排序。
- 修改 spec
- PR/review 完成後佈署
- 在任務上加入狀態(待處理、進行中、完成)
- 【選項】可考慮使用管理狀態的 gem
- 在列表頁面,要能夠以標題和狀態進行查詢
- 【選項】可考慮使用 ransack 等 gem
- 在設定條件查詢時,請觀察 log 並確認 SQL 的變化
- 之後的步驟也需要這麼做,請養成習慣
- 建立搜尋索引(index)
- 準備一定程度的測試資料後,觀察 log/development.log 以確認加入 index 後對速度的改善
- 【選項】使用 PostgreSQL 的
explain
等功能,檢視資料庫端的 index 使用狀況
- 針對查詢功能增加 Model spec(feature spec 也可能需視情況修改)
- 在任務上加入優先順序(高、中、低)
- 列表頁可依優先順序做排序
- 修改 feature spec
- PR/review 完成後佈署
- 使用
kaminari
或其它類似的 gem 在列表頁面加入分頁功能。
- 使用 Bootstrap 5 或 Tailwind CSS,為目前的作品套入設計
- 【選項】自己寫 CSS 調整設計
- 建立使用者 Model
- 以 seed 建立第一個使用者
- 建立使用者和任務的關聯
- 建立關聯所需的 index
- 要避免 N+1 問題
- ※ 再次部署到雲端平台時,已經建立過的任務,要和使用者建立關係(資料維護)
- 為了能更深入了解 Rails 中 HTTP cookie 和 session 的原理並加強對一般認證機制的理解(例如密碼的處理),請不使用任何現成的 Gem,自己實做會員系統
- 實做登入的頁面
- 未登入時,不能進入任務管理頁面
- 請改成只能看到自己建立的任務
- 實做登出功能
- 在頁面上新增管理選單。
- 管理頁面的網址
/admin
。- 在修改
routes.rb
之前,請想一下 URL 以及 routing name(會變成*_path
的部分)要怎麼設計。
- 在修改
- 實做使用者的列表、新增、修改、刪除等功能。
- 刪除使用者後,也一併刪除該使用者的任務。
- 在使用者列表頁面,顯示使用者的任務數量。
- 能夠看到使用者所建立的任務列表。
- 將使用者分為管理員和一般使用者
- 設定只有管理員可以存取使用者管理頁面
- 若一般使用者存取管理頁面時,需提示權限不足訊息無法存取,並轉向適當頁面
- 能在使用者管理頁面選擇角色
- 管理者只剩下一個人時,不能再被刪除
- ※ 可以自己決定是否要使用現成套件
- 一個任務可以設定多個的標籤
- 能夠以標籤進行搜尋
- 客制化 Rails 的預設錯誤頁面
- 根據不同狀況,設定適合的錯誤頁面
- 至少需要做 404 和 500 這兩頁
辛苦了,恭喜你已經完成本次教材!
另外,雖然沒有包括在教程中,以下這些主題也是必要的技能,希望各位能漸漸掌握(大部分會在專案開發的過程中學習到)。
- 加深對網站應用程式的基本理解
- HTTP 與 HTTPS
- Rails 稍微進階一點的用法
- STI
- logging
- explicit transactions
- 非同步處理
- asset pipeline(佈署方面)
- JavaScript、CSS 等 frontend 技術
- 資料庫
- SQL
- query 的效能
- index
- Server 環境
- Linux
- Web server(nginx)的設定
- Application Server(Passenger)的設定
- PostgreSQL 的設定
- 佈署工具
- Capistrano
有別於前述的必修課題,任務管理系統還有以下選修課題。要做到什麼程度,請和導師一起討論決定。
- 在登入時提醒有接近或超過結束時間的任務
- 如果能做出已讀、未讀狀態更好
- 任務可讓多個的使用者檢視或進行修改
- 例:在學員和導師之間共享
- 顯示任務作者
- 選修課題 2 的延續
- 新增群組設定的功能,並增加群組內分享的功能
- 讓任務可以上傳附加檔案
- 使用 Heroku 的話,要能夠管理上傳到 S3 bucket 的檔案
- 請使用適合的 Gem
- 讓使用者可以設定大頭照
- 由於上傳的檔案會被當成 icon 使用,請做成 thumbnail
- 請使用適合的 Gem
- 為了將結束時間視覺化,在日曆上以結束時間來顯示任務
- 可以自己決定是否要使用其它套件
- 在任務列表中,加入以拖曳方式排序的功能
- 來把統計資料視覺化吧
- 圖表的形式,要簡單易懂
- 可以自己決定是否要使用其它套件
- 任務接近結束時間時,在背景以 email 進行通知
- 使用雲端服務來發信
- Heroku 的話就是 SendGrid
- VPS 的話就是 MailGun 或是公司的 Postal
- 以一天一次的頻率,批次發信
- Heroku 的話用 Heroku Scheduler(add-on)
- VPS 的話就設定 cron job
- 用 Certbot 申請 letsencrypt 憑證並設定在 Nginx 上