1、Rack

使用者點擊網站,傳request的流程

> request -> web server -> rack -> ruby(erb)  

1-1、Rake定義

Rake的定義是,只要做一個物件,這個物件可以call,並且回傳一個包含三個元素的陣列,三個元素包含
(1) 網頁狀態(數字)
(2) HTTP Header(hash)
(3) HTTP Body(陣列)

Ps. 只要支援call方法就可以,中介軟體也支援rack

> run Proc.new { |env|                      -> 用 run 去執行rack
>     [
>         500,                              -> http 狀態
>         {'Content-Type' => 'text/html'},  -> http header (這個也有其他型態'text/jpg/img'之類的)  
>         ['hellos rack']                   -> http body
>     ]
> }

1-2、http status 網頁常見狀態

資訊回應 (Informational responses, 100–199),
成功回應 (Successful responses, 200–299),
重定向 (Redirects, 300–399),
用戶端錯誤 (Client errors, 400–499),
伺服器端錯誤 (Server errors, 500–599).


301、302的差異
301會永久轉傳網址,302只是暫時
永久換網址用301
暫時修網站用302


1-3、run回傳一個環境變數

環境變數會給一包東西 -> 對方瀏覽器的情況(ip位置、瀏覽器一些資訊……)

> class Cat
>     def call(env)                               -> 這裡可以把一大包環境變數印出來
>         p env
>         [
>             500,
>             {'Content-Type' => 'text/html'},
>             ['hellos rack']
>         ]
>     end
> end
> kitty = Cat.new
> run kitty

2、中介軟體 middleware

中介軟體執行時間,是在run物件開始前,他除了可以當run的入口,也可以當插在入口前的東西

> class Backdoor
>     def initialize(app, who = "no one")
>         @app = app
>         @who = who
>     end
> 
>     def call(env)
>         status, header, body = @app.call(env)
> 
>         body << "<br /> hacked by #{@app}"
> 
>         [ status, header, body ]
>     end
> end
> 
> 
> use Backdoor, "YeeeeeeeChen"                  -> 執行中介軟體
> 
> 
> run Proc.new { |env|                          -> 入口
>     [
>         500,
>         {'Content-Type' => 'text/html'},
>         ['hellos rack']
>     ]
> }

2-1、use Backdoor

use Backdoor -> 在use的時候,會做下面兩件事,之後初始化的參數,就是下面那個(B)
Ps. 我最想知道的東西,就是這個,中介變數傳上去的app變數,就是這裡來的

> B = Backdoor.new(R)
> run B

3、rails 路徑、架構

  1. 瀏覽者的request傳進web server
  2. web server去找路徑
    • (1) 有的話就去找相對應controller
    • (2) 沒有的話丟一包狀態404的rack給瀏覽者
  3. 設定routes時,會controller會有相對應的action,在controller設定好action
  4. 最後進到action會要你去view頁面找相對應的erb檔案
>                                    action action ----->|   |       |     一堆的
>                                      ^    ^            |   |       |     table、table
>       |            |                 |    |            |   |       | SQL | - - - - - - - - - - - -  
> req ->| web server | -> routes -> Controller -> action---->| model | =>  |  DB (SQ Lite、MySQL)  |
>       |            |                             |     |   |       |     | - - - - - - - - - - - -
>                                                  |     |   |       |            | 
>  webview <-----------------------------  view <--------    |       |  <=========|       
>                                                            |       |     資料集(給SQL抓到的陣列)
>                                                            |       |     

3-1、routes setting

routes寫法,這一行的意思是,進入/about網址後,要去找pages這個controller,並且controller裡面要有ab這個action

get "/about", to: "pages#ab"  

如果使用者request網址,沒有這一條路徑,就會丟404+另外兩個狀態回去,如果有的話,就連到controller
ex. /about -> 連到about相關的controller


3-2、rails g/d controller

> rails g controller pages   -> 生成一個指定controller檔案
> rails d controller pages   -> 刪除一個指定controller檔案

3-3、render html: “hi”

這樣寫在action上,可以直接產出html的內容(不用連到view頁面)

> def ab
>     render html: "hi"           -> 這樣畫面可以印出hi
> end

首頁路徑寫法
get “/”, to: “pages#home” -> 舊寫法
root “pages#home” -> 新寫法


4-1、Turbolinks做了什麼?

Turbolinks會攔截畫面所有的a-link,如果發現此link是站內連結,會啟用這個方法

當你在A頁面按下去B頁面連結的時候,會用ajax的方式去抓連結頁面的內容,會直接把B頁的內容,改成A頁的內容
header換header、body換body、網址換網址

4-2、Turbolinks為什麼要這樣做

為什麼要這樣換?因為這樣速度很快,傳統換頁,速度再怎麼快還是會閃一下,用turbo方法的話會超快
Ps. 可以到f12的地方,點選網路狀態,會發現網頁載入狀態是xml

4-3、Turbolinks缺點

不過這樣會發生一件事,還記得JS的defer渲染嗎,當你每當換一頁,就會渲染一次
不過現在Turbolinks不會有換頁行為,所以dom事件只會在網頁載入當下觸發一次,之後換網頁都不會觸發
那其他頁面的dom元素要怎麼觸發呢?下面這一篇文章可以解決這個問題


rails 怎麼解決JS DOM無法觸發的問題
這篇一定要讀,解決了dom無法觸發的問題


<a href="/about">關於我們</a>

使用這個好處是,link_to是一個方法,可以增加一些想要的參數進去

> <%= link_to '聯絡我們', "/about" %> . -> a網址寫法
> <%= link_to '聯絡我們', about_path %> -> rails routes寫法 (相對路徑 -> 只會有/about)
> <%= link_to '聯絡我們', about_url %> -> rails routes寫法 (絕對路徑 -> 完整的網址(會員驗證信))

rails routes介紹
prefix = 自首、前綴
Verb = 動詞
URI Pattern = 連結類型
Controller#Action = action的指向controller
用prefix_path當做路徑的好處在,想要換網址的時候,直接在路徑的地方換就好,會全換


5-3、.:format介紹

queryString -> 查詢字串(這個很重要)
透過網址的參數列,你想要傳給controller的時候就會用到,在網址列的東西會被params抓下來 Ps. 一般的關鍵字查詢用get就可以做了,不需要用到post

首先在view的erb打上,接下來就會印出搭配網址所抓到的一堆hash

<%= params %>

假設網址為/contact

{"controller"=>"pages", "action"=>"contact"}

假設網址為/contact?a=2&b=2

{"a"=>"2", "b"=>"2", "controller"=>"pages", "action"=>"contact"}

假設網址為/contact.apple
這個.apple就會被params抓下來,變成 “format”=>”apple”

{"controller"=>"pages", "action"=>"contact", "format"=>"apple"}

假設今天想要在路徑那邊設複雜一點

> get "/contact(.:query)", to: "pages#contact"   -> contact後面多加一個.:query

這樣params起來會變怎樣呢?網址為/contact

> {"controller"=>"pages", "action"=>"contact"}

上面看起來沒啥變對不對,我們現在幫網址多加一點料
網址為/contact.apple.banana

> {"controller"=>"pages", "action"=>"contact", "query"=>"apple", "format"=>"banana"}

> 可以發現路徑設定的query,變成key值了

之後如果要設定搜尋表單,就可以利用指定的key值,吐給你value值,並把value塞進search bar欄位

6、Model

6-1、rails g model

model規格定好後,就可以下指令了

> rails g model WishList title description:text

> 會產生已向兩個檔案
>  create    db/migrate/20221114073329_create_wish_lists.rb     -> migrate
>  create    app/models/wish_list.rb                            -> model

建立好model後,記得實體化

> rails db:migrate

產生model注意事項 (1) 專案名稱、model名稱一樣,會遇到model無法產生的問題
(2) t.timestamps -> 這個會產生兩個欄位 -> created_at、updated_at


6-2、spring stop


Spring地雷
如果今天migrate完,又再migrate一次,會出現一行spring preloader(預先載入)的東西
如果把專案丟到垃圾桶,但是 Spring 已經先幫你預載了,所以有機會在新開rails new,會卡住

遇到這種狀況,把spring停下來,新專案就可以繼續了,那要怎麼停下來呢?
輸入spring stop,就可以把spring停下來


6-3、model VS table

model table 補充
WishList wish_list 在rails的格式
O O 兩者都有最常見
O X 購物車,只有model,不用table
X O rails內建table

Ps. 做購物車,不用把資料存到table,可以使用sessions就好

6-4、rails g migration 增加某個model的欄位

直接開一個新的migration,直接打在schema打資料是無效的!!
Ps. 欄位名字不要亂取

rails g migration add_online_to_wish_list

migration沒有存檔
要小心migration沒存檔,就db:migrate,會導致欄位沒有新增,就把migration用掉了
解決方法,用db:rollback把migration倒回去,並存檔migration檔案,最後再一次db:migrate


6-5、rails db:rollback


把表格刪除,不建議直接對表格做,把表格砍掉有風險(因為資料會全部不見)


6-5、rails db:migrate:reset


這個指令可以把整個資料表倒掉,並且快速重新db:migrate


7、ps - process status 查看程序執行狀況

輸入ps可以看目前指定程序的執行狀況

假設今天想看local:3000的所有程式執行狀況,可以這樣輸入

> ps aux | grep 3000  

這個可以抓出local:3000執行中的程式
下面是正在執行的程式,36327是該執行序的編號

> yee0526          36327   0.0  0.0 408104048   1456 s005  S+    2:15下午   0:00.00 grep 3000

使用kill把某個執行中的程式強制停止

> kill 36327

Ps. 要找aux是啥可以打下面的指令

> man ps