2018/1/2

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

markdown 這是目前我們理解的 HTTP 協定。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDDd1WmueuUPejQ2gCRQbVDSFbInhKL0oyAmw7sNqyig12R8zvki2y6erh0SWsyOjik9de9uR51K80kpdtT0fNOlP5zjoCBn_5Oggl4Cg74MLvclMcd24E2AvKj1EfiuzQxkSIWODcDcY/s1600/1.jpg) 今天會詳細說明 Rails 是怎麼處理一個 HTTP Request。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4g95h3LW5Mx3WOdL0uJ-WN9GPCgAz2VV7L7ZzHPgf4zai5c37xlMsWqYvef7lH2ye7QWxFkIzdGd8hlVpPYi3zzCHUCWHHRt9X0ZfpaxdsxJHC8V-dH09xgvluzFhB2rZahNoz1zeOQg/s1600/2.jpg) 當我們在瀏覽器輸入一個網址時,會發出一個 Get Request 到網頁伺服器。網頁伺服器會根據這個網址,決定他應該要幹嘛。而 Rails 中的 Route 負責分析網址, Route 會決定要把 Request 發給哪一個 Controller 的 Action 來做回應。因為 Action 畫上去圖會很亂,所以就乾脆不畫了。 應該很難懂吧? 用人話來說:Route 就像大樓警衛,當有信件送進來,他要負責把信交給對應的住戶,所以 Controller 就是住家,Action 就是裡面的人。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiJvFOxKgtGVh-butNSV3OF4VjZ0pVUM0Y_NIIZMIcMZZdCipS2KWDYXgM6O2nehpsiuX39wV5hhyphenhypheneqpqKCthCdGqv1IGa26QETANR-7ywVmNczv9pCl8JJOu7AvNdI6MHWhqspWIlLQA/s1600/3.jpg) 當然,一棟大樓會有一間警衛室,以及有很多住戶,而且每一戶裡面還有住很多人,但是一封信只會寄給一個人。 # 所以我說那個警衛室在哪? 先打開 sublime text,然後點左上角的 `File`(檔案)。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio98LWPjpMfPCkWhOHKuV_ggbon44B0ALKpgZrQiyC6Nx3og4DS6WoVNSUBZZmZHgSGfUR3bVyHXGdo84mvyJu9dv_VM1yUVqtAdUahrKm0ll3mnG_g57vgJfgAZ0-ZyJYqO2oinLfTbA/s1600/4.jpg) 選擇 `Open Folder...`(打開資料夾),選到我們的專案資料夾:`D:\只要有心,人人都可以作卡米狗\ironman`。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-ZL43UH34UAXlwpFN5dIZgyjbBEQyN92eadc9Icl3aqv_AkrJE8f6VrW7S08dWK9UURNXEjX701gvN9RpRnK4U_2UWGChyphenhyphenOuTWxJVqbyUY3XhMiT8lGd9_GJkfDuU-hsOh3SixDgqNhc/s1600/5.jpg) 按下`選擇資料夾`。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7EAS3iZpjgIu7256kzEz4hECrVGF0X5oNRcVNldn3_V2MyJDIUgrRMe6AQpgA-jhbSEZvgcZdEww3sdg0XGJGzFjrkCRL4SNN9XCMNaiVCOdyJfIIkuNhstamqeSbKAsMJBEwNJm5Qxg/s1600/6.jpg) 左側多了一塊是資料夾目錄,那個灰色邊界是可以拖曳的,像這樣: ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeblXfWUwiTu5EVnEYRPywNB558gi3umtgPJBuj1fOzolx5xPmSRGuhXQx2FdgFStGYyF6LyKUMwXXKQ587crB3MmS77cBcGxPqpByC9C5hrjwj6Uj7COBR1BwFwbusZdF0Q3-K19Jwpo/s1600/7.jpg) 如果覺得空間不夠大,可以自行調整。 我們的警衛室在 `config/routes.rb`,先點左側的 `config` 資料夾,點一下會展開,再點一下會收合,然後再點一下 `routes.rb`。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGr7MCEVhVUkFS-xOzpRY_fwWwXJSMettVkjAFsdyYhZdA7Frd1G2wxxYhlkm3fpUGXT8wAP1UALJ_ziH9Nh964B7RoVnAn63vaobONPG8QbPUpssO7L0a-2cbyi_J81yI5jnbKDbQJGU/s1600/8.jpg) 這樣就是空的。 # 那我們的住戶呢? 住戶在 `app/controllers`。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcyEaaQIF5MyNLftPwLwx9aWLHMBKtA3JEiVfD6qB6CJT3APmYVBeagPJaVbhMV9WFsH9Pbs07wbueM-NQAdvk1U449pHwD3f18S1xXKLVC9RvpaIYdMaScBtaSUZDo3z9GTRT4lcBWtg/s1600/9.jpg) 看到一個 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`。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjASP0Ei1jZ7qEw8pvzkIJcgaBiTBIV1l1iFRFZPuWP2QC_WefW4pZF3glczpSRMtXO4wLZsfhMqSfVftCpKysQJMO-_jsxo-26ZeiFCnPao1p9YBeyDwarX9TJ9wUX2acdPlxGpcn-wY0/s1600/10.jpg) # 我後悔了想復原怎麼辦? 我們可以用 `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` 目錄上按右鍵。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhpdNu41HWxkUMPNcEGSWagKL6kdhUmLJ2nyBU_ETBX7bmBWhzZKUhWBsfllb9tsDMckjiAw97qZ2jhqBZbuaxwBEszv-ZuqQYuUsHukEtEcwF948QMDUoA4vl83ThPNJ9o0kj82VdFW0/s1600/11.jpg) 選 `New File`。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG1Dc8JslNB1pRKZfTDMYz0bXcXB5zw1VMCDPKBCbo7_unnKFSyrVigCHgSV3SPcP3NCVJIQOzjsFrcQK7Bi3mc9_vdpez4hyiTX9_up9q2HcqLu8nIHK6sDyuaey_DkMH9AYPt92vy-Y/s1600/12.jpg) 在新的檔案裡填入我們想要的程式碼: ``` class KamigoController < ApplicationController end ``` 然後按下 `Ctrl`+`S` 存檔。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgleLrv_RT_c5AjScQ-I94wKi3bXMJRj4KK8T3Fi8qtq0iUBID5BjMQ0TRbyD7tfPpPUErQzpD03i-vgtpCYaGuE8B-h7cp0lwfJiYCZxOPn3vSP-hunE2sMDZgv5QcBkP1El64N_xHLF0/s1600/14.jpg) 輸入檔名:`kamigo_controller.rb`,副檔名 `.rb` 是 ruby 的意思,這樣 sublime text 就能知道內文是 ruby 程式碼。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieHtEzaTFMXGX5L-Gsv-PY6CQ9gQk0JSVHp1i7GF8r3pD7ijkhyc3ARUkPLSCVRAuWkzfpGivkKiF-kDRkxTVgwc526t6vrEN3N5T_hd_qE14Zgu8bBFcxMMpxTX6NbKaZKSPfdAWhOU8/s1600/15.jpg) 自從我用了 sublime text 之後,人生就變成彩色的呢! 前面有提到 controller 是一戶,每一戶裡面還要有人,所以我們弄點人進去。 # 加入 action 我們定義一個叫做 `eat` 的空方法。 ``` class KamigoController < ApplicationController def eat end end ``` 注意看這裡: ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn1Ep3DQVa6acNQ6rWlrsCwBgeGLwUDlZg_NWZOAVHCNjHMKRwN6FiARp58Y1Pz1o-VbbwuWO-C77lh68brlnOi66g70vBdXMAktJoUy8gvz2n14Zqvg5jXCxko6xyhSXUK6YQHJx5BuE/s1600/16.jpg) 他是一個灰色圈圈,代表這個檔案編輯過,但還沒存檔,按下 `Ctrl`+`S` 之後就會變成灰色X,像這樣: ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSHBBCCU9hHnnbkfgCmfMcp42P5WzyTmubKJeJjr2yA7D5U8e1ik3y2EveoZapyKykXVo4NknpaXzqrgM5mrUTUq2bcgj0WgEBS3S7gp9uNRF5voURcx74q70PBl3Ik7MhNK8Tcc1e5P8/s1600/17.jpg) 現在我們已經有一戶,而且住了一個人了,我們來請警衛幫我們轉信。 # 加入 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](http://localhost:3000/kamigo/eat),然後就爆炸了: ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHkka8-AzbNbUdz1GMWat2O_PwWaEuc5G5-zA0VsIZFMNrmHs9bOQAPwcQbnd59ARXCKVAMnfEJOvb9p-SNiGobUSfEKQCsiYpglju0SDoGL031BL8n_iTnwITx9MQQGTRzHZj0FIz17I/s1600/18.jpg) 是一個很眼熟的爆炸,這招我們在[第九天:作一個最簡單的 Rails 網站](https://ithelp.ithome.com.tw/articles/10194359)就玩過了。這是因為 Rails 找不到對應的 html 檔案,所以爆炸。可是我們並沒有在 eat 裡面要求 Rails 去找檔案呀!原來這是 Rails 的預設行為。要修好這個問題有兩個方法: - 在正確的地方新增一個網頁 - 為了避免 Rails 亂幫我們做事,我們得明確說明我們想幹嘛 兩種我們都要會。 ### 在正確的地方新增網頁 網頁應該要放在 `app/views/kamigo/` 下,檔名需要叫做 `eat.html` 或者 `eat.html.erb`。 在 sublime text 新增資料夾的方法是在 `views` 資料夾點右鍵: ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1RaLqXOmoken4WK9olqnFq88vDTeWT7t9botyDu4uM3iZcwUWS4Gd2ZuthHsOlMbwtVDyItpMFDHUwbpTe3H6NdvkwmOcfyl3YwlTAEK3384xOj6AZjfVB3v4AGiNPShxx1lhqORvshs/s1600/20.jpg) 點選 `New Folder...`: ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1FT8GgwDYKjcf60yuI0ciaRW9V_Dh9nsK16m4oDHHJ9Jqd67nkOJdaHvdfvWLUS1xRQ3euSfDn2Jdh0Mvj8Yn6sGYWniRebGxZHyPWsMUzHfgxgQgZa_94femKkIrfy2ypj2RpQhw980/s1600/21.jpg) 輸入 `kamigo` 後按 `Enter`,資料夾就新增完成了。如果你不喜歡這樣,你也可以回到檔案總管去新增資料夾。 然後新增 `eat.html` 檔案,在裡面寫你想要吃的東西。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXlybjzHMgKMBoWa12PnKw3BztTVLt1zboLV5r9NsJs9bfuYh8Mxq4AooPXTiV1XetDkvPZJizsSHKxxkXwvqGaEGPe6Hb0-LHKyJfU7nzRWu9x-Q855iFycyxDVXGvwDJWucMeneXV5o/s1600/22.jpg) 再開一次網址看他有沒有修好:[http://localhost:3000/kamigo/eat](http://localhost:3000/kamigo/eat) ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz0o0IfSZZBF7gTYfXJ5GbuXu-c1DyqQ8HAmJl2mG15QJaTuV373Ycb6ONuXZM0tP-VCoHrKsLEz2pqGFYr9XfjCPy-jKPawJPTVh8PpRpdC7wnxuP-J3lUQHkIeqyZyovXfC1q4SFudA/s1600/23.jpg) 修好了! ### 為了避免 Rails 亂幫我們做事,我們得明確說明我們想幹嘛 把 `app/controllers/kamigo_controller.rb` 檔案改成下面的內容後存檔: ``` class KamigoController < ApplicationController def eat render plain: "吃土啦" end end ``` 我們加入了一行程式碼 `render plain: "吃土啦"`,意思是我們要用純文字`"吃土啦"`來回應這個請求,這樣 Rails 就不會用預設的網頁路徑作為回應了。 再開一次網址看他有沒有變化:[http://localhost:3000/kamigo/eat](http://localhost:3000/kamigo/eat)。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqGMNuknKbp8NPVilWr9REa8oY00fIjd_LGqyR8328383ZzfQ9TxSPXyYTgykiuJcZy959V8ggYpRp-lBfb3MPsWp-XjPdjLPJkG7lW6OyuRr_6mgrfn8OWSJv9qpIYtibjNfidLjonX0/s1600/24.jpg) 卡米狗好兇阿。 # 總結 - 今天了解到 Rails 最基本的運作流程 - 對於 Sublime Text 的操作又更加熟悉了 明天我們要從 Rails 的角度觀察 HTTP 協定。

沒有留言: