本教程的主要課題,是要開發一套任務管理系統。這個系統需要做到的事情有:
- 可以簡單地登錄自己的任務
- 可以設定任務的結束時間
- 可以設定任務的優先順序
- 可以管理各種狀態(待處理、進行中、完成)
- 可以依狀態列出不同任務
- 可以依任務的標題、內容進行搜尋
- 可以看到任務的列表,並依優先順序、結束時間等進行排序
- 可以為任務加上分類標籤
- 可以讓使用者登入,並只能看見自己建立的任務
滿足以上需求之後,還會需要如下的管理機制:
- 使用者的管理功能
- 預設需要支援 macOS/Chrome 的最新版本
請以下列程式語言、middleware 的最新版本進行開發。
- Ruby
- Ruby on Rails
- PostgreSQL
server 端請使用:
- Heroku
- 如果你是 DevOps 相關,請在 Linode 或 Digital Ocean 或 Vultr 上建立一台 VM
- CentOS 7
- 安裝 Ruby / PostgreSQL 或其它專案需要的東西
※ 本教程中對效能、資安沒有特別的要求,但仍需要有一定的品質。網站效能太差的話,會被要求改善。
完成本教程後,我們會認為你已經習得以下能力:
- 可以實做基本的 Rails 網站
- 可以將 Rails 專案上線至一般的環境
- 對於已經上線的 Rails 專案,能夠進行功能的追加和資料維護
- 知道如何在 GitHub 發 PR、merge 等協作流程,以及必須的 git 指令
- 能將 commit 切成適度的大小
- 能寫出適合的 PR 說明
- 能針對 code review 進行修正
- 遇到問題時,能夠適時以口頭或線上工具向相關人員(在本例中為導師)求救
- Git: https://gitbook.tw/
- Rails: https://railsbook.tw/
- 以 gem 指令安裝 Rails
- 安裝最新版本的 Rails
- 以
rails -v指令來確認 Rails 的版本
- 在你使用的 OS 下安裝 PostgreSQL
- macOS 的話,請以
brew等工具安裝
- macOS 的話,請以
- 在你的環境中安裝 git
- macOS 的話,請以
brew等工具安裝 - 以
git config設定 user name 和 email
- macOS 的話,請以
- 請考慮專案名稱(也等於 repo 名稱)
- 建立 repo
- 如果沒有帳號的話,先申請帳號
- 接著產生空白的 repo
- 以
rails new指令,建立 app 最低限度的樣板和檔案 - 在
rails new產生的專案目錄下,建立docs資料夾,並將本教程文件 commit 進去- 搬進來是為了方便之後開發時可以參考
- 將成品 push 到 GitHub 的 repo
- 將使用的 Ruby 版號寫進
Gemfile(也請確認 Rails 版號是否有標明)
- 開始進行設計之前,先和導師一起討論對最終成品的預想。建議在紙上畫 prototype
- 請參照網站需求,開始想需要怎樣的資料結構
- 需要哪些 model (table)?
- table 會需要哪些欄位?
- 有想法之後,將 model 關係圖手繪出來
- 完成後將關係圖拍照存檔,放進 repo 裡
- 把 table schema 寫進
README.md(model 名稱、欄位名稱、資料形態)
※ 在這個階段,model 關係圖不需要是完全正確的。以現在所能預想的範圍來規劃就好(做到後面的步驟,發現需要修改時再來調整的概念)
- 先建立新的 git topic branch
- 之後都在 topic branch 上開發並 commit
- 安裝 bundler
- 在
Gemfile安裝pg(PostgreSQL 的 adapter) - 設定
database.yml - 以
rails db:create建立資料庫 - 以
rails db確認有正確連接資料庫 - 在 GitHub 上建立 PR 並請人 review
- 必要時,請在 PR 上標柱 WIP(work in progress)
- 收到 comment 後就做必要的處置。收到兩個 LGTM(looks good to me) 後就可以 merge 回 master
開始來做管理任務所需要的 CRUD。 一開始先簡單做,只要能記錄名字和任務內容即可。
- 以
rails generate指令建立 CRUD 所需的 model class - 撰寫 migration 並以此建立 table
- 非常重要:migration 要確定能安全回到上一步的狀態!請養成以
redo確認的習慣
- 非常重要:migration 要確定能安全回到上一步的狀態!請養成以
- 以
rails c指令,透過 model 確認有正確連接資料庫- 順便試著以 ActiveRecord 建立資料
- 在 GitHub 上發 PR 並請人 review
- 製作任務的列表、新增、檢視、修改頁面
- 以
rails generate指令產生 controller- 請和導師討論要用哪一種 template engine
- 實做 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 之類的 CI 工具,每次 Push 自動跑 Spec
- 太難的話可以請導師幫忙設定
- 利用 Rails 的 i18n 功能,將 View / Controller / Model 中的語言部份共用化
※ i18n 化的好處是,之後的步驟中,各種訊息的處理會輕鬆很多
- 將 Rails 的時區設為台灣(台北)
- 現在是以 id 排序,請試著讓它以建立時間排序
- 完成後,撰寫 feature spec
- 開始設定資料驗證
- 請思考需要在哪個欄位上加入哪種驗證比較好
- 與之配合的 DB 限制,請寫成 migration
- 以
rails generate指令產生 migration file
- 在頁面上加入驗證的錯誤訊息
- 撰寫對應的 model 測試
- 在 GitHub 上發 PR 並請人 review
- 來將 master branch 上的簡易任務管理系統推上線吧
- 試著將網站 deploy 到 Heroku 上
- 沒有帳號的話,請建立帳號
- 戳一下被推上 Heroku 的網站
- 接下來就會在這裡建立任務並繼續開發
- ※ 不過,推上 Heroku 後,就是在網路上公開了,請注意不要放敏感資料
- 現階段,或許可以考慮加入 basic 認證
- 今後,每個步驟完成後,就繼續將成品推上 Heroku
- 將佈署的方法寫進
README.md- 也將使用的 framework 版號等資料記下來
- 註冊服務商(Linode / DO / Vultr)帳號或登入
- 開機器(1G Ram 機種,OS 用 CENTOS 7 x64)並加入自己的 SSH KEY
- 用普通的方式1或普通的方式2安裝必要的套件和 CRuby
- 安裝必要的其它套件
- 請使用 Passenger + Nginx 做為 Application Server 和 Web Front-End Server
- 讓任務可以設定結束時間
- 讓列表頁能夠以結束時間排序
- 擴充 spec
- PR/review 後佈署
- 在任務上加入狀態(待處理、進行中、完成)
- 【選項】不是初學者的話,可以使用管理 state 的 gem
- 在列表頁面,要能夠以標題和狀態進行查詢
- 【選項】不是初學者的話,可以使用 ransack 等 gem
- 在設定條件查詢時,請觀察 log 並確認 SQL 的變化
- 之後的步驟也需要這麼做,請養成習慣
- 建立 search index
- 準備一定程度的測試資料後,觀察 log/development.log 以確認加入 index 後對速度的改善
- 【選項】使用 PostreSQL 的 explain 等功能,檢視資料庫端的 index 使用狀況
- 針對查詢功能增加 model spec(feature spec 也要擴充)
- 在任務上加入優先順序(高中低)
- 能夠以優先順序做排序
- 擴充 feature spec
- PR/review 後 佈署(以下同)
- 使用 kaminari gem 在列表頁面加入分頁功能
- 導入 bootstrap,為目前為止的作品套入設計
- 【選項】自己寫 CSS 來設計
- 建立使用者 model
- 以 seed 建立第一個使用者
- 建立使用者和任務的關聯
- 建立關聯所需的 index
- 設計上要注意避免 N+1 問題
- ※ 推上 Heroku 時,已經建立過的任務,要和使用者建立關係(資料維護)
- 這裡不能使用 gem,請自己實做
- 不使用 devise 等 gem,是為了讓新人能更深入了解 Rails 中 HTTP cookie 和 session 的原理
- 以及加強對一般認證機制的理解(例如密碼的處理)
- 實做登入的頁面
- 未登入時,不能進入任務管理頁面
- 請改成只能看到自己建立的任務
- 實做登出功能
- 在頁面上新增管理選單
- 管理頁面的網址一定要以
/admin開頭- 在修改
routes.rb之前,請想一下 URL 以及 routing name(會變成*_path的部分)要怎麼設計
- 在修改
- 實做使用者列表、新增、修改、刪除等功能
- 刪除使用者後,也一併刪除該使用者的任務
- 在使用者列表頁面,顯示使用者的任務數量
- 能夠看到使用者所建立的任務列表
- 將使用者分為管理員和一般使用者
- 請改成只有管理員可以存取使用者管理頁面
- 一般使用者存取管理頁面時,需要有專用的例外處理
- 補充來說,例如適當的錯誤頁面(也可以在步驟 24 再實做)
- 能在使用者管理頁面選擇角色
- 管理者只剩下一個人時,不能再被刪除
- 利用 model 的 callback 實做
- ※ 可以自己決定是否要使用 gem
- 任務可以設定複數的標籤
- 能夠以標籤進行搜尋
- 將 Rails 的預設錯誤頁面換成自己的
- 根據不同狀況,設定適合的錯誤頁面
- 至少需要做 404 和 500 這兩頁
辛苦了,恭喜你已經完成本次教程!
另外,雖然沒有包括在教程中,以下這些主題也是必要的技能,希望各位能漸漸掌握(大部分會在專案開發的過程中學習到)。
- 加深對網站應用程式的基本理解
- HTTP 與 HTTPS
- Rails 稍微進階一點的用法
- STI
- logging
- explicit transactions
- 非同步處理
- asset pipeline(佈署方面)
- JavaScript、CSS 等 frontend 技術
- 資料庫
- SQL
- query 的效能
- index
- server 環境
- Linux OS (CentOS)
- web server(nginx)的設定
- application server(Passenger)的設定
- PostgreSQL 的設定
- 佈署工具
- Capistrano
有別於前述的必修課題,任務管理系統還有以下選修課題。要做到什麼程度,請和導師一起討論決定。
- 在登入時提醒有接近或超過結束時間的任務
- 如果能區別已讀、未讀狀態更好
- 希望可以讓複數的使用者檢視、修改同樣的任務
- 例:在新人和導師之間共享
- 需要顯示任務作者
- 選修課題2的延續
- 新增群組設定的功能,並增加群組內分享的功能
- 讓任務可以上傳附加檔案
- 使用 Heroku 的話,要能夠管理上傳到 S3 bucket 的檔案
- 請使用適合的 gem
- 讓使用者可以設定大頭照
- 由於上傳的檔案會被當成 icon 使用,請做成 thumbnail
- 請使用適合的 gem
- 為了將結束時間視覺化,在日曆上以結束時間來顯示任務
- 可以自己決定是否要使用 library
- 在任務列表中,加入以拖曳方式排序的功能
- 來把統計資料視覺化吧
- 圖表的形式,要簡單易懂
- 任務接近結束時間時,在背景以 email 進行通知
- 使用雲端服務來發信
- Heroku 的話就是 SendGrid
- VPS 的話就是 MailGun 或是公司的 Postal
- 以一天一次的頻率,批次發信
- Heroku 的話用 Heroku Scheduler(add-on)
- VPS 的話就設定 cron job
- 用 Certbot 申請 letsencrypt 憑證並設定在 Nginx 上