###### tags: `Ruby & Rails`
# 20221114 Rails 建立WishSite專案
[TOC]
---
<政庭>
<h2 id="1">Rack (不是Rake!!!) 是一個介面</h2>
* A Ruby webserver interface
* 介面就是幫忙做翻譯
* 架子:顧名思義,可以放很多的middileware
* Ruby on Rails 其實也是一中Rack應用程式
<h2 id="2">Rack 規格</h2>
* 能夠回應call方法的物件
* 回應格式包含以下3個元素的陣列
* 狀態狀態數字,表頭,狀態
* 回應格式:{狀態;header;body}
```ruby
[
200,
request header{"content-type" => "text/jpeg/image/html", "server"=> "cloudflare"},
request body["內文"]
]
```
<h2 id="3">
回應的狀態
</h2>
* 100-199
* 200-299(成功連線)
* 300-399(redirection轉址)
* 400-499(client端的錯誤)
* 500-599(server端的錯誤)
<h2 id="4">呼叫 config.ru</h2>
* 裡面會有一個run XXXXXXXX
<h2 id="5">Rails 應用程式</h2>
<h2 id="6">Route 路徑對照表(路口阿姨)</h2>
* 路口的阿姨,你可以詢問他我要找誰誰誰
* 阿姨會告訴你,該怎麼找他
* 發現找不到怎麼辦,我們就做給他

<h2 id="7">其實404 頁面也是有它自己的[status,header,body]</h2>
<h2 id="8">turbolink</h2>
* 在頁面切換的時候 Rails 使用的方法叫做Turbolink
* 假設今天有站內的 A頁面 要切換到 B頁面
* 利用ajax的方式,把B頁面的body換到A頁面的body上
* 讓換頁面的速度更快
* 所以turbolink,可以説個笑話"turbolink是假超連結"
<h2 id="9">prdfix_path</h2>

<h2 id="10">queryString 查詢字串</h2>
* 網址列的查詢字串
<h2 id="11">Model 它是一個class</h2>
* 它是一個抽象的查詢模型,會對應到資料庫裡的某個table
* table包含:id / title / desciption

<h2 id="12">SQL 資料庫查詢語法</h2>
## rails db:migrate 前 要記得先存檔!!!
## rails db:migrate 前 要記得先存檔!!!
## rails db:migrate 前 要記得先存檔!!!
<h2 id="13">ER 圖(Enity-Relationship-Diagram)</h2>
* 專案實作的時候,使用工具軟體畫出ER圖
* 可以幫助你知知道每個 table 的關聯性
---
<侑庭>
## Rack
* Rack 是放在 Ruby 跟WebSever 中間的一個介面做翻譯
* middleware 在架子上每一層都可以放一些東西
* Ruby on Rails 其實也是一種rack的應用程式
## 規格
* 能夠回應Call 方法,並回傳一個狀態,header,body
```ruby=
{
200,
{"content-type" => "text/jpeg/image/html"}, #
["內文"]
}
```
## Route
* 當使用這Req進來的時候 routes 會先確認路徑存不存在,不存在就給他一個404
* routes 就像一個詢問站會分配每個人到哪個地方或是去哪個樓層才能做這件事情
* 決定網站的方向,改變網站
## controller
* 由routse 丟過來的使用這 在經由controller 去找相對應的action
## 實際操作
1. new 一個新的專案之後 要先去找routesd看看有沒有路徑如果沒有我們就做一個給他
```ruby=
Rails.application.routes.draw do
get "/about" , to: "pages#about"
end
```
這時候我們開啟rails sever 看看會跑出什麼東西

## MVC
* 當我們在routes 建立的新的路徑會發現,建立文之後如果我們直接建立view 的時候正常要先建立action,但當我們直接建立view的時候會發現其實不用透過action也可以,但我們還是乖乖建立action
## turbolinks
* 利用ajax非同步原理 ,主要做的就是看似換頁但其實只是利用非同步原理將畫面抓回來而不是換頁,所以當畫面上看到的時候不會有換頁的閃跳,但這主要是要用在站內, 站外的話就還是需要轉跳
## link_to helpper
* `<%= link_to "要顯示的字樣", "/要去的地方"%>` 用它來取代a,link_to也是一種方法,讓後需如果需要更改會更容易更改
* 當然如果都解決對路徑在後續修改上面就會有問題,所以我們去問了routes 可以用給我們的路徑對照表Prefix 給的字首就可以輕易修改
```ruby=
<%= link_to "關於", "/about"%>
<%= link_to "關於", about_path%>
<%= link_to "關於", about_url%>
```
* path 只會抓出站內的簡易路徑
* url 就會抓出完整得路徑

## model
* model像是翻譯年糕,用SQL語法跟資料庫溝通,然等資料庫回傳拿到table,在經過model翻譯變成類似像Array的東西但本質不是Array
* 以ruby角度來看他是一個class(類別)
* 資料庫就像EXL,而裡面有很多的table也就像是EXL下面的頁籤
* 在new一個新的model時會產生兩個最重要的東西一個在model內新增一個當案,另外會在db的migrate檔案中同時會新增另外一個檔案入如下圖


* 超級重要就是在new model的時候不能跟專案同樣名字不然就會出現以下錯誤

* 在rails中 在沒有選資料庫的狀況下會預設`adapter: sqlite3` 但當然有缺點 sqlite 沒有boolen 但adapter他像是轉接頭會主動把 true跟false >轉乘 0跟1 , 可以到database.yml 去看資料庫

* 如何在新增一個欄位,因為已經migrate過了所以不能重複可以使用db:rollback 到回去drop掉原來的table,但這樣做會有風險,如果原本有資料在裡面就會全部不見,與其倒退回去不如直接新增migration 但我目前只做出了檔案還沒新增欄位
* 新增欄位用`add_column: :表格名稱, :欄位名稱, :資料型態` 用這方式其他人下載資料就會跳出沒有db:migrate 提醒所有人表格欄位有更新!
[add_column參考資料](https://https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_column)
---
<于婷>
## Rack(架子)
### 規格:
回應call方法,回傳一個陣列,包含:
1. http狀態(200成功,301永久/302暫時 轉移位置,401 需要輸入帳密,403 需要授權,404使用者的瀏覽器找錯地方,500內部伺服器問題)
2. header頁面(hash),告訴伺服器要用什麼方式渲染
3. body內文
```ruby=
{
200,
{"content-Type" => "text/html"},
["內文"]
}
```
## rackup
```ruby=
class Cat
def call(env)
[
200,
{"content-type" => "text/html"},
["hello world"]
]
end
end
kitty= Cat.new
run kitty
```
## rails 網頁建置步驟
**快捷鍵control+p可快速找到需要檔案**
### routes.rb(路徑)
```ruby=
get "/about", to: "pages#about"
```
### $(終端機)
```ruby=
$ rails g controller pages
```
### pages_controller.rb(中控台)
```ruby=
def about
end
```
### about.html.erb(畫面)
```ruby=
<h1>關於我們</h1>
```
### 超連結寫法
```ruby=
<a href="/about">關於</a>
<%= link_to "關於", "/about" %>
<%= link_to "關於", about_path %> #相對路徑
<%= link_to "關於", about_url %> #絕對路徑
```
### 新增欄位
```
$ rails g migration add_online_to_wish_list
```
```
add_column :wish_lists, :online, :boolean, default: false
```
**記得存檔**
```
$ rails db:migrate
```
---