2018/1/2

第十四天:最基本的 Rails 運作流程( 2018 iT邦幫忙鐵人賽-只要有心,人人都可以作卡米狗 )

這是目前我們理解的 HTTP 協定。

今天會詳細說明 Rails 是怎麼處理一個 HTTP Request。

當我們在瀏覽器輸入一個網址時,會發出一個 Get Request 到網頁伺服器。網頁伺服器會根據這個網址,決定他應該要幹嘛。而 Rails 中的 Route 負責分析網址, Route 會決定要把 Request 發給哪一個 Controller 的 Action 來做回應。因為 Action 畫上去圖會很亂,所以就乾脆不畫了。

應該很難懂吧?

用人話來說:Route 就像大樓警衛,當有信件送進來,他要負責把信交給對應的住戶,所以 Controller 就是住家,Action 就是裡面的人。

當然,一棟大樓會有一間警衛室,以及有很多住戶,而且每一戶裡面還有住很多人,但是一封信只會寄給一個人。

所以我說那個警衛室在哪?

先打開 sublime text,然後點左上角的 File(檔案)。

選擇 Open Folder...(打開資料夾),選到我們的專案資料夾:D:\只要有心,人人都可以作卡米狗\ironman

按下選擇資料夾

左側多了一塊是資料夾目錄,那個灰色邊界是可以拖曳的,像這樣:

如果覺得空間不夠大,可以自行調整。

我們的警衛室在 config/routes.rb,先點左側的 config 資料夾,點一下會展開,再點一下會收合,然後再點一下 routes.rb

這樣就是空的。

那我們的住戶呢?

住戶在 app/controllers

看到一個 concerns 空的資料夾和一個 application_controller.rb,現階段就當作沒看到這個檔案好了。

所以我們現在蓋的樓裡面根本沒住人!總之還是先弄個住戶進去再說。

做一個 Controller

先開啟 cmd 到我們的專案目錄:

D:\只要有心,人人都可以作卡米狗\ironman>

輸入 rails generate controller kamigo ,請 rails 幫我們生成一個叫做 kamigo 的 controller。

D:\只要有心,人人都可以作卡米狗\ironman>rails generate controller kamigo
      create  app/controllers/kamigo_controller.rb
      invoke  erb
      create    app/views/kamigo
      invoke  test_unit
      create    test/controllers/kamigo_controller_test.rb
      invoke  helper
      create    app/helpers/kamigo_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/kamigo.coffee
      invoke    scss
      create      app/assets/stylesheets/kamigo.scss

D:\只要有心,人人都可以作卡米狗\ironman>

他幫我們產生了好多檔案,開頭有 create 的那些都是,但是其實我們只需要 app/controllers/kamigo_controller.rb

我後悔了想復原怎麼辦?

我們可以用 rails destroy controller kamigo 來刪除這些檔案。

D:\只要有心,人人都可以作卡米狗\ironman>rails destroy controller kamigo
      remove  app/controllers/kamigo_controller.rb
      invoke  erb
      remove    app/views/kamigo
      invoke  test_unit
      remove    test/controllers/kamigo_controller_test.rb
      invoke  helper
      remove    app/helpers/kamigo_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      remove      app/assets/javascripts/kamigo.coffee
      invoke    scss
      remove      app/assets/stylesheets/kamigo.scss

D:\只要有心,人人都可以作卡米狗\ironman>

這次我們手動新增 controller

在左側的 controllers 目錄上按右鍵。

New File

在新的檔案裡填入我們想要的程式碼:

class KamigoController < ApplicationController
end

然後按下 Ctrl+S 存檔。

輸入檔名:kamigo_controller.rb,副檔名 .rb 是 ruby 的意思,這樣 sublime text 就能知道內文是 ruby 程式碼。

自從我用了 sublime text 之後,人生就變成彩色的呢!

前面有提到 controller 是一戶,每一戶裡面還要有人,所以我們弄點人進去。

加入 action

我們定義一個叫做 eat 的空方法。

class KamigoController < ApplicationController
  def eat
  end
end

注意看這裡:

他是一個灰色圈圈,代表這個檔案編輯過,但還沒存檔,按下 Ctrl+S 之後就會變成灰色X,像這樣:

現在我們已經有一戶,而且住了一個人了,我們來請警衛幫我們轉信。

加入 route

我們把 config/routes.rb 改成這樣:

Rails.application.routes.draw do
  get '/kamigo/eat', to: 'kamigo#eat'
end

get '/kamigo/eat', to: 'kamigo#eat' 的意思是當有人在瀏覽器輸入網址 /kamigo/eat 時,就把請求交給 kamigo 這個 controller 裡的 eat 方法來回應。

測試一下

在 cmd 輸入 rails s 開啟網頁伺服器:

D:\只要有心,人人都可以作卡米狗\ironman>rails s
=> Booting Puma
=> Rails 5.1.4 application starting in development
=> Run `rails server -h` for more startup options
*** SIGUSR2 not implemented, signal based restart unavailable!
*** SIGUSR1 not implemented, signal based restart unavailable!
*** SIGHUP not implemented, signal based logs reopening unavailable!
Puma starting in single mode...
* Version 3.11.0 (ruby 2.4.2-p198), codename: Love Song
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

用瀏覽器開啟這個網址:http://localhost:3000/kamigo/eat,然後就爆炸了:

是一個很眼熟的爆炸,這招我們在第九天:作一個最簡單的 Rails 網站就玩過了。這是因為 Rails 找不到對應的 html 檔案,所以爆炸。可是我們並沒有在 eat 裡面要求 Rails 去找檔案呀!原來這是 Rails 的預設行為。要修好這個問題有兩個方法:

  • 在正確的地方新增一個網頁
  • 為了避免 Rails 亂幫我們做事,我們得明確說明我們想幹嘛

兩種我們都要會。

在正確的地方新增網頁

網頁應該要放在 app/views/kamigo/ 下,檔名需要叫做 eat.html 或者 eat.html.erb

在 sublime text 新增資料夾的方法是在 views 資料夾點右鍵:

點選 New Folder...

輸入 kamigo 後按 Enter,資料夾就新增完成了。如果你不喜歡這樣,你也可以回到檔案總管去新增資料夾。

然後新增 eat.html 檔案,在裡面寫你想要吃的東西。

再開一次網址看他有沒有修好:http://localhost:3000/kamigo/eat

修好了!

為了避免 Rails 亂幫我們做事,我們得明確說明我們想幹嘛

app/controllers/kamigo_controller.rb 檔案改成下面的內容後存檔:

class KamigoController < ApplicationController
  def eat
    render plain: "吃土啦"
  end 
end

我們加入了一行程式碼 render plain: "吃土啦",意思是我們要用純文字"吃土啦"來回應這個請求,這樣 Rails 就不會用預設的網頁路徑作為回應了。

再開一次網址看他有沒有變化:http://localhost:3000/kamigo/eat

卡米狗好兇阿。

總結

  • 今天了解到 Rails 最基本的運作流程
  • 對於 Sublime Text 的操作又更加熟悉了

明天我們要從 Rails 的角度觀察 HTTP 協定。

沒有留言: