Upgrade to Pro — share decks privately, control downloads, hide ads and more …

有效結構化你的 Rails 專案

tsechingho
August 02, 2020

有效結構化你的 Rails 專案

將使用數種實際的範例,講述如何結構化專案邏輯與 UI 畫面。

建議使用多層的 Namespace 來結構化專案的業務邏輯,每個業務流程須講究獨立運作。

當不同角色的業務邏輯 UI 畫面不一樣時,該如何使用前後端技術有效率實作,並保留容易擴充的彈性,將是本次探討的重點。

使用 Rails 開發專案,務必不要死守 MVC 架構,Presenter、Form Object、Query Context 等都是你的好朋友。Rails 的 Form Builder 是很有彈性的,可以串接 ActiveRecord 以外的物件,重點是如何做好表單驗證、錯誤處理、巢狀表單。將會示範如何靈活運用這些物件。

最容易將專案越搞越複雜的方式,大多發生於

1. 相似的業務流程,直接使用同一個流程,加上很多 if else 條件。
2. 不同的角色,有類似的 UI,使用很多 if else 條件去 render 不同的 patial 檔案。

以上無視眾多的小差異積累的威力,就會造成牽一髮動全身,讓專案變得難以維護。將會示範幾項手法來處理這問題。

使用 Rails view 或 React 實作 UI 端(Server / Client Side Render)的基本守則是類似的,因此可以做到遊走於兩種實作方法的。將會示範基本做法。

tsechingho

August 02, 2020
Tweet

More Decks by tsechingho

Other Decks in Technology

Transcript

  1. 何澤清 TSECHINGHO, 2020-08-02, COSCUP TAIWAN
    有效結構化你的 Rails 專案
    改變思維很重要!
    不斷調整思維更重要!!!

    View full-size slide

  2. 何澤清
    tsechingho
    ⿈碼科技

    View full-size slide

  3. 邏輯需求

    View full-size slide

  4. 複合式商店 - 購物⽅式
    • 購物⾞
    • 可放置多樣商品+型號
    • 可移除商品
    • 可選數量
    • 可放置加購商品
    • 所有商品⼀起結帳
    • 智能購物⾞
    • 主動折扣(符合條件)
    • 即時拆單(分批結帳)

    View full-size slide

  5. ⼀⾴式商店 - 單品購物
    • 單品+立即結帳
    • 各型號獨立
    • 不可選數量
    • 不可搭配加購商品
    • 樣式:按鈕
    • 單品選購+立即結帳
    • 型號可單選
    • 可選數量
    • 可搭配加購商品
    • 樣式:選項+按鈕

    View full-size slide

  6. ⼀⾴式商店 - 系列商品購物
    • 系列商品+立即結帳
    • 各商品+型號獨立結帳
    • 不可選數量
    • 不可搭配加購商品
    • 樣式:分區(按鈕)
    • 例:劃位售票
    • 系列商品選購+立即結帳
    • 可多選商品+型號⼀起結帳
    • 可選數量
    • 可搭配加購商品
    • 樣式:分區(選項+按鈕)
    • 例:冷凍鍋物(⽺⾁爐 )

    View full-size slide

  7. ⼀⾴式商店 - 綑綁商品購物
    • 綑綁商品+立即結帳
    • 各綑綁商品獨立結帳
    • 不可選數量
    • 不可搭配加購商品
    • 樣式:分區(按鈕)
    • 例:限量公仔
    • 綑綁商品選購+立即結帳
    • 可複選綑綁商品⼀起結帳
    • 可選數量
    • 可搭配加購商品
    • 樣式:分區(選項+按鈕)
    • 例:募資商品

    View full-size slide

  8. 線上商店 - 結帳流程
    • 折扣
    • 抵⽤(點數)
    • 優惠(合作)
    • ⾦流
    • ATM、超商條碼
    • 信⽤卡、線上⽀付
    • 發票、電⼦發票
    • ⼆聯式、三聯式、捐贈
    • 載具
    • 物流
    • 超商取貨、超商付款取貨
    • 郵寄、宅配、貨到付款

    View full-size slide

  9. 複合式商店 - ⾏銷 + 結帳
    • 免費領取
    • 零元兌換
    • 等價兌換
    • 折價兌換
    • 全站折扣碼
    • 指定商品折扣碼
    • 分類(館)折扣碼
    • VIP 卡
    • 活動折扣
    • 經常性、季節
    • 特惠、廠商合作
    • 加購優惠

    View full-size slide

  10. UI 設計需求

    View full-size slide

  11. 依照角⾊ - 所需⾴⾯組成不同
    • 線上課程平台
    • 訪客
    • 學員
    • 講師
    • 學院
    • 平台
    • 外送平台
    • 顧客
    • 外送員
    • 店家
    • 平台

    View full-size slide

  12. 依照流程 - 呈現元素排列不同
    • 貨運單(送件 -> 收件)
    • 空運 - ⾶機, 空港, 轉運站
    • 海運 - 貨船, 海港, 海關
    • 陸運 - 卡⾞, 集貨中⼼, 收貨點
    • 購物
    • 購物⾞
    • ⼀⾴購物

    View full-size slide

  13. N 角⾊ x N 流程 =

    View full-size slide

  14. Client / Server Side Render !?

    View full-size slide

  15. SEO + Page Speed 兼顧 !?

    View full-size slide

  16. 突破舊思維

    View full-size slide

  17. 學會 Rails 不只是 …
    • 只會 MVC 架構
    • 只會在 Model 做 Validation
    • 只會寫⼀⼤串 ActiveRecord 的 where 條件查資料庫
    • 只會⽤ view helper 簡化 view 取得資料的複雜度
    • 只會拿 Form Builder 串接 ActiveRecord 或 Ransack 物件
    • 只會⽤ if … else … 切割流程

    View full-size slide

  18. 至少要活⽤ …
    • ActiveHash / ActiveYaml / ActiveJson 當作資料物件
    • Query Context 作為跨資料物件查詢的仲介層
    • Presenter / Decorator 作為 view 的資料來源
    • Form Object 作為表單驗證的把關者
    • Service Object 作為串接外部服務的⿊盒⼦
    • Operator / Flow Object 作為控制流程的中⼼物件

    View full-size slide

  19. 最好再加碼 ...
    • React.js / Vue.js
    • Webpack / ?
    • AMP
    • PWA

    View full-size slide

  20. 迎接新思維

    View full-size slide

  21. 善⽤ Route 切割業務邏輯
    • Admin 和 API 都知道要切成 namespace,為何其他功能不切 namespace?
    • 除了切出 namespace,也能切成 subdomain 做到獨立。
    • 既然會掛 rails engine 的 routes 到專案,為何 routes.rb 不切割成數個檔案?

    View full-size slide

  22. Rails View 層越簡潔越好
    • 多點 Layout 不是壞事,仿照 AMP 只放該⾴⾯需要的 JS、CSS 和資料
    • 同個 namespace 的 partial file 不要放到其他 namespace 資料夾
    • 改⽤ Presenter 為主、Decorator 為輔,少⽤ view helper
    • 資料要遵守 Single Source of True 原則
    • 避免多層的 if … else …,儘量只⽤ if 就好
    • 最後⼤概只剩 HTML + CSS classnames + methods + Loops + if 的結構

    View full-size slide

  23. Namespace 是業務邏輯⼿段
    • 每個業務邏輯都要有⾃⼰的 module ( namespace )
    • 流程控制邏輯 / UI 呈現邏輯 / 資料存取邏輯
    • Controller / View / Model => web page
    • Operator / Presenter / Query Context => page section (components)
    • 放 app 或 lib 資料夾
    • 寫成 rails engine 放專案內,或發佈成 ruby gem

    View full-size slide

  24. Namespace 依類型區分
    • app/contexts
    • carts/query_context.rb
    • orders/query_context.rb
    • app/forms
    • carts/update_form.rb
    • orders/create_form.rb
    • app/presenters
    • carts/popup_presenter.rb
    • orders/details_presenter.rb
    • app/services
    • payments/create_service.rb
    • callbacks/update_service.rb

    View full-size slide

  25. Namespace 依需求區分 I
    • app/learning
    • carts
    • query_context.rb
    • update_form.rb
    • popup_presenter.rb
    • app/teaching
    • orders
    • query_context.rb
    • create_form.rb
    • details_presenter.rb

    View full-size slide

  26. Namespace 依需求區分 II
    • app/components/learning
    • carts
    • popup_presenter.rb
    • app/objects/learning
    • carts
    • query_context.rb
    • update_form.rb

    View full-size slide

  27. golden-objects
    https://github.com/goldenio/
    golden-objects

    View full-size slide

  28. React.js + Rails
    • 不做需要 SEO 的 web page 或 page section 才⽤ React
    • 需要 SEO 的⾴⾯⽤ AMP (in rails view)
    • React 資料夾切割以⾴⾯為單位
    • API 端點依需求 namespace 切割 (例:learning vs teaching)
    • Presenter -> json.jbuilder -> React component props

    View full-size slide

  29. 程式範疇 -> 架構範疇
    Namespace
    ->
    Micro service

    View full-size slide