--- tags: - Rails Develoepr Foundation - Rails 開發者的進階實戰 --- # 2023-05-28 - Rails 開發者的進階實戰 ## 事前準備 考慮到練習的時間,課程基本上會以 Pair/Mob Programming 的形式進行,然而仍建議有自己的開發環境方便未來練習。 ### 開發環境 請以能夠運行這個 [GitHub Repository](https://github.com/StarPortal/rails-developer-foundation-template) 的前提下安裝環境,相關的安裝說明可以參考 README 的內容。 | 環境 | 版本 | |-------------|-------| | Ruby | 3.2+ | | PostgreSQL | 14 | | Node.js | 18 | | [Cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/) | 2023+ | #### 命令 請確認可以確運行以下命令 | 命令 | 說明 |------------------------|---------------------------- | `bundle exec cucumber` | 驗收測試用,本次課程只會使用這個 | `bundle exec rspec` | 單元測試用 | `./bin/dev` | Rails 伺服器 ### 工具 上課過程會使用以下工具 | 名稱 | 說明 | |------------------|---------------------------------| | FigJam | 需求分析練習,請確認瀏覽器可以正常開啟 | | JetBrains Client | 安裝連結上課當天公布 | | 習慣的編輯器 | VSCode、Vim 等皆可 | ## 課後問卷 麻煩大家協助填寫改善課程品質,以及了解大家對哪些類型的內容更有興趣 https://www.surveycake.com/s/vKRQO ## 講師資訊 課程內容無法涵蓋的部分,可以追蹤網誌、YouTube 會以小單元或者系列連載的方式分享出來。 | 網站 | 介紹 | |-----------------|------| | [個人網誌](https://blog.aotoki.me) | 系列文章連載、主題式討論 | [Facebook 粉絲專頁](https://fb.me/aotoki.me) | 主題式討論 | [YouTube 頻道](https://www.youtube.com/channel/UCcABbJfCL0DfNh3wDk_-7lg) | 技術講解 | [Discord 社群](https://discord.com/invite/t2Kd6PNvvA) | 技術討論,上課的問題也可以在此發問 | [訂閱電子報](https://mailchi.mp/aotoki/rails-developer-foundation) | 即時收到網誌通知 ## 實作練習 為了方便查詢最近上映的電影,我們決定實作一個查詢網站來取得最近推出的幾部電影。 > https://github.com/elct9620/classroom-2023-05-28 ### Key Examples * 當蒼時開啟列表頁面時,顯示最新的 5 筆電影 * 假設有三部電影 * 2023-06-04 SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 * 2023-05-23 小美人魚 * 2023-05-17 玩命關頭X * 當蒼時開啟列表頁面 * 那麼會看到 1. SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 2. 小美人魚 3. 玩命關頭X ```gherkin #language: zh-TW 功能: 影片列表 場景: 當蒼時開啟列表頁面時,顯示最新的 5 筆電影 假設 這裡有幾部電影 | date | name | | 2023-06-04 | SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 | | 2023-05-23 | 小美人魚 | | 2023-05-17 | 玩命關頭X | 當 開啟電影列表 那麼 會看到 "1. SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播" 並且 會看到 "2. 小美人魚" 並且 會看到 "3. 玩命關頭X" ``` ```ruby= Given('這裡有幾部電影') do |table| table.hashes.each do |movie| # ... end end When('開啟電影列表') do visit movies_path end Then('會看到 {string}') do |string| expect(page).to have_text(string) end ``` * 當蒼時在列表頁面輸入「最近 1」的時候,可以看到離當天日期最近的 1 部電影 * 假設有三部電影 * 2023-06-04 SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 * 2023-05-23 小美人魚 * 2023-05-17 玩命關頭X * 當蒼時開啟列表頁面 * 並且輸入 "最近 1" * 並且點選 "查詢" * 那麼會看到 * 1. 小美人魚 ```gherkin= #language: zh-TW 功能: 影片列表 背景: 假設 這裡有幾部電影 | date | name | | 2023-06-04 | SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 | | 2023-05-23 | 小美人魚 | | 2023-05-17 | 玩命關頭X | 場景: 當蒼時開啟列表頁面時,顯示最新的 5 筆電影 當 開啟電影列表 那麼 會看到 "1. SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播" 並且 會看到 "2. 小美人魚" 並且 會看到 "3. 玩命關頭X" @wip 場景: 當蒼時在列表頁面輸入「最近 1」的時候,可以看到離當天日期最近的 1 部電影 當 開啟電影列表 並且 在 "Search" 填入 "最近 1" 並且 點選 "查詢" 那麼 會看到 "1. 小美人魚" ``` ```ruby= When('在 {string} 填入 {string}') do |label, value| fill_in label, with: value end When('點選 {string}') do |text| click_on text end ``` * 當蒼時在列表頁面輸入「最新 1」的時候,可以看到最新公開的 1 部電影 * 假設有三部電影 * 2023-06-04 SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 * 2023-05-23 小美人魚 * 2023-05-17 玩命關頭X * 並且還有一部電影 * 2023-06-07 變形金剛:萬獸崛起 * 當蒼時開啟列表頁面 * 並且輸入 "最近 1" * 並且點選 "查詢" * 那麼會看到 * 1. 變形金剛:萬獸崛起 ```gherkin 場景: 當蒼時在列表頁面輸入「最新 1」的時候,可以看到最新公開的 1 部電影 假設 這裡有幾部電影 | date | name | | 2023-06-07 | 變形金剛:萬獸崛起 | 當 開啟電影列表 並且 在 "Search" 填入 "最新 1" 並且 點選 "查詢" 那麼 會看到 "1. 變形金剛:萬獸崛起" ``` ```ruby= class Movie include AcitveModel::Model include ActiveModel::Attributes end ``` ```ruby # controller class MoviesController < ApplicationController def index @movies = if params[:search] == '最近 1' Movie.recently(1) elsif params[:search] == '最新 1' Movie.newest(1) else Movie.all end end end ``` ```ruby # model class Movie attr_reader :date, :name class << self def all [ Movie.new(date: '2023-06-04', name: 'SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播'), Movie.new(date: '2023-05-23', name: '小美人魚'), Movie.new(date: '2023-05-17', name: '玩命關頭X') ] end def recently(qty) base_date = Date.current all.each_with_object({}) do |movie, result| date_diff = ((base_date - Date.parse(movie.date)).to_i).abs result[date_diff] = movie end.sort_by { |date_diff, _movie| date_diff }.map { |_date_diff, moive| moive }.first(qty) end def newest(qty) [Movie.new(date: '2023-06-07', name: '變形金剛:萬獸崛起')] end end def initialize(date:, name:) @date = date @name = name end end ``` * 當蒼時在列表頁面輸入「最新 3」的時候,可以看到最新公開的 3 部電影 * 假設有三部電影 * 2023-06-04 SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 * 2023-05-23 小美人魚 * 2023-05-17 玩命關頭X * 並且還有一部電影 * 2023-06-07 變形金剛:萬獸崛起 * 當蒼時開啟列表頁面 * 並且輸入 "最近 1" * 並且點選 "查詢" * 那麼會看到 * 1. 變形金剛:萬獸崛起 * 2. SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 * 3. 小美人魚 ```gherkin 場景: 當蒼時在列表頁面輸入「最新 3」的時候,可以看到最新公開的 3 部電影 假設 這裡有幾部電影 | date | name | | 2023-06-07 | 變形金剛:萬獸崛起 | 當 開啟電影列表 並且 在 "Search" 填入 "最新 3" 並且 點選 "查詢" 那麼 會看到 "1. 變形金剛:萬獸崛起" 並且 會看到 "2. SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播" 並且 會看到 "3. 小美人魚" ``` > 額外挑戰: > * 如何不透過資料庫串接真實資料(e.g. 威秀) > * 如何改寫成 LINE Bot > * 如何用 LINE 的 Carousel 方式呈現跟測試? * 當蒼時輸入非關鍵字的訊息時,固定回覆 "請使用「動作 參數」的格式處理" * 當蒼時輸入「最新 1」的時候,可以看到上映日期最晚的 1 部電影 * 假設有三部電影 * 2023-06-04 SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 * 2023-05-23 小美人魚 * 2023-05-17 玩命關頭X * 當 "蒼時" 輸入 "最新 1" * 那麼結果包含 "SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播" * 當蒼時輸入「最近 1」的時候,可以看到離當天日期最近的 1 部電影 * 假設有三部電影 * 2023-06-04 SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 * 2023-05-23 小美人魚 * 2023-05-17 玩命關頭X * 當 "蒼時" 輸入 "最近 1" * 那麼結果包含 "小美人魚" * 當蒼時輸入「最近 5」的時候,可以看到離當天日期最近的 5 部電影 * 假設有三部電影 * 2023-06-04 SANKYO PRESENTS WALKURE FINAL LIVE TOUR 現場直播 * 2023-05-23 小美人魚 * 2023-05-17 玩命關頭X * 當 "蒼時" 輸入 "最近 5" * 那麼結果包含 "小美人魚" * 並且結果包含 "玩命關頭X" ## 共筆區域 > 歡迎在這裡撰寫筆記跟其他同學協力紀錄 > [name=蒼時弦や]