---
# System prepended metadata

title: 2023-05-28 - Rails 開發者的進階實戰
tags: [Rails 開發者的進階實戰, Rails Develoepr Foundation]

---

---
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=蒼時弦や]