---
# System prepended metadata

title: 五倍先修課程-Rails

---

# 五倍先修課程-Rails

## 什麼是Ruby on Rails?(RoR)
* 是用Ruby做出來的網站開發框架
* 發明人為 David Heinemeier Hansson(DHH)
* 首次發表為2004年

### 兩大設計原則
1. DRY (Don't repeat yourself)不做重複的事
2. COC (Convention over configuration)慣例優於設定



---

## 環境安裝

1. 打開ubuntu
2. 輸入 `gem install rails` 
2-1.  `gem install rails -v (版本序號)`可以指定版本下載
2-2. `gem install rails --pre` 安裝嘗鮮版本
3. 在終端機輸入rails -v查看版本
4. 輸入 `rails new XXX` 產生新專案
5. 輸入`cd 專案名稱` 進入該專案資料夾
6. 終端機指令 `rails server`
7. 順利的話可以看見成功字樣(若失敗可以嘗試著看失敗的文字找尋解答)
8. 輸入localhost:3000 看見rails成功字樣表示安裝成功
小提醒:(輸入sudo可以進入root最高權限)

---
## 常用終端機指令

1. cd => 切換目錄
    1-1. cd .. => 切換至上一層
    1-2. cd - => 回到上一次我在的地方
2. pwd => 我現在在什麼地方
3. ls => 秀出我目前的資料夾有哪些檔案
    3-1. ls -l => 更完整的檔案
    3-2. ls -a => 將隱藏的檔案也一並顯示
4. clear => 清楚上述資料(將上述資料往上讓畫面變乾淨)
    或者CTRL +L 也是同樣效果
5. Ctrl + W => 清除一個字(一個單字的意思)
6. Ctrl + U => 整串文字刪除
7. Ctrl + R => 進入歷史搜尋打上您要搜尋的關鍵字
8. touch 檔案名稱(index.html) => 就會產生一個新的檔案
9. rm 黨案名稱 => 永久刪除檔案
10. mkdir 資料夾名稱 => 新增資料夾
11. rm -r 資料夾名稱 => 刪除資料夾
12. cp 舊檔案 要複製的檔案名稱 => 複製檔案
13. mv 舊檔案 更改後的檔案名稱 => 更改檔案名稱

![](https://i.imgur.com/RImvT80.png)


---

## 建立第一個應用程式

### 使用者資料表table

需要有使用者的ID、NAME、EMAIL以及TEL 來做新增修改刪除。

1. 使用scaffold語法，輸入`rails generate scaffold User name:string email:string tel:string`或  
`rails g scaffold User name email tel`
#ID欄位不需要設置，scaffold語法已經有包含ID欄位了
#除了String型態之外都不可省略

2. 會建立在db:migrate裡，之後在終端機輸入 rails db:migrate 將資料表具現化
3. 啟動rails server
4. 輸入http://localhost:3000/users 即成功
![](https://i.imgur.com/ajm6DMY.png)

那麼scaffold又幫我們做了什麼事情呢? 幫我們建立了MVC架構(Model、View、Controller)，MVC又是什麼?

---

## MVC結構(Model、View、Controller)

![](https://i.imgur.com/hKIDy3A.png)

流程: 一個使用者進入一個網站後，先經過Route(類似導覽的角色)後會告訴你這個業務要去哪裡辦法，之後引導至Controller裡面，內有許多action，像是今天你要辦理業務有許多業務，看你要辦哪種業務告訴完Controller後他會請Model當翻譯蒟蒻，至資料庫內調閱你所需要的資料，再將其回傳，但因為調回來的資料一般使用者看不懂所以要在請View將資料美化後回傳，最終得到使用者所想看到的畫面。

總結:總共有四個部門(R+MVC)
Route => 引導部門，引導到你所需要的Controller
Controller => 控制部門，選擇你要處理的業務(acion)
Model => 調閱資料部門，至資料庫調閱你所需要的資料
View => 美編部門，負責將資料美化到讓使用者看得懂的文件(會回傳html的方法)

---
## Migration是什麼?

1. 用來描述資料表的樣子
2. 紀錄每一個欄位的變化
3. 版本控制

---

## 製作第二個文章資料表
<img style="width:50%;" src="https://i.imgur.com/qfLWUOA.png" alt="" >

1. 使用scaffold語法，輸入`rails generate scaffold Post titlee content:text is_available:boolean user:references`
2. 輸入 `rails db:migrate` 具現化資料
 #user_id:integer = user:references
3. 啟動rails server

### 控制台模式(rails console)

在終端機輸入 `rails console` or `rails c` 啟動控制台模式可以查詢rails專案的內容
例如`Post.first` # 印出在Post上的第一篇文章

<img src="https://i.imgur.com/ok3alXM.png
" alt="" >

#### 中控台模式和Irb的差別是?

rails的中控台模式會把所有rails的環境與檔案等等載入進來直接操作，但irb只是一個單純的寫Ruby的模式

---

## collection_select 製作下拉選單

一般寫文章時使用者不可能會知道自己的User_id是多少是不會自己填寫的，所以要先來寫一個符合邏輯的user寫法

1.找到 view/posts/_form.html.erb檔將 

```htmlmixed=
<div class="field">
    <%= form.label :user_id %>
    <%= form.user_id %>
  </div>
```
改成
```htmlmixed=
<div class="field">
    <%= form.label :user_id %>
    <%= form.collection_select(:user_id,User.all,:id,:name) %>
  </div>
```
![](https://i.imgur.com/Klr6tO4.png)

**詳細的collection_select 需要多加練習 看不太懂啊!!!!**

---

## N+1問題

何謂n+1問題?

![](https://i.imgur.com/Y1xkfeG.png)
![](https://i.imgur.com/bDAGSxw.png)
在終端機會顯示你總共往資料庫調閱了幾次資料，很明顯的第一次是先從資料庫調閱出posts的所有文章，接下來的四次都是在說明為了調閱User的id所以每一篇文章都要再往users裡搜尋id，總共執行了 4 + 1 次往資料庫搜尋的次數，雖然都是暫存但也挺浪費資源的。

為了避免有此問題發生只要到controller/posts_controller.rb檔將
```htmlmixed=
 def index
    @posts = Post.all
  end
```
輸入 `.includes(:user)` 語法即可

```htmlmixed=
 def index
    @posts = Post.all.includes(:user)
  end
```
![](https://i.imgur.com/DM5cSr0.png)


---

## 資料驗證

前端驗證 vs 後端驗證

前端驗證 => 使用JS判斷送出表單前如果格式不對..等等可以直接將資料檔下來
後端驗證 => 寫進資料庫前如果內容不對..等等直接擋下來

**不能只靠前端驗證!容易被躲 前端防君子不防小人! 切記!!!!**

因為Model掌管資料，所以到Model/user.rb裡新增validates語法

```ruby=
class User < ApplicationRecord
  has_many :posts
  validates :name,presence: true # presence表這個資料是否存在
end
```
<img style="width:50%;" src="https://i.imgur.com/uKmWyE5.png" alt="" >

還有其他更多驗證器，可以再上網搜尋相關資料，不只有presence!!!

<img style="width:30%;" src="https://i.imgur.com/SmYc9ve.png" alt="" >

```ruby=
class User < ApplicationRecord
  has_many :posts

  validates :name,presence: true, length: { is: 3 } #要存在且長度要等於三

end
```
<img style="width:50%;" src="https://i.imgur.com/7trXDtP.png" alt="" >

---









