# Ruby(06/14) 五倍紅寶石(第八屆共筆)(2021/8/10)
## TDD:(很重要!)
測試驅動開發,重點是開發
- 功能:
寫程式確認另一段 code 能否正常運作,因為重複的東西用機器來做可以自動化且省時間
- 用法:
先規劃好,畫好藍圖,再實做內容
先寫測試再寫程式,測試不存在的功能,假設他能正常運作
先把結果(規格)寫出來,確定是壞的再修正,如果遇到錯誤就一個一個修正,不要期待一開始就會是對的
- 結構:
整體簡單清楚易懂就好,不要用複雜的語法
- why?
- 本身是規格
- 做出比較好的設計
- 可以重構
- 更有信心的程式碼
- why 不寫?
- 沒時間:大專案反而會節省時間
- 跑測試太慢:會慢一點點,但可自動幫你抓bug,好處 > 壞處
- 很脆弱:只能怪自己改不動
- 不會寫:學著寫,練習從結果推回去
- 面試題:
- 怎麼測不存在的東西?
假設他存在
- 要測什麼?
看需求
### 測試套件
- minitest:執行快
- RSpec(Ruby Specification):Ruby 規格,主流套件,要額外安裝,執行慢,語法易懂
### 參考書
- The Pragmatic Pookshelf 書局
- Programming Ruby
- Rails 5 Test Prescription (處方籤)
- RSpec3!
- Everyday Rails Testing with RSpec!
- OREILLY
---
## Rails evernote
### 資料清洗
- .any?:有沒有東西
- .errors.any?:有沒有錯誤
- .errors.full_message:錯誤訊息
### SCSS SASS
超級 CSS,比一般 CSS 更好用
### 實做
notes_controller.rb
```rb
class NotesController < ApplicationController
# GET 顯示所有資料
def index
# @notes = Note.all
# 排序交給資料庫做 :desc做反向排列
# 不要做 Note.all.sort.reverse
# 可寫 all 可不寫,當你沒有要做其他事就寫 all
@notes = Note.order(id: :desc)
end
# GET 到新頁面建立資料
def new
@note = Note.new
end
# POST 寫入資料庫
def create
# title = params[:title]
# content = params[:content]
# 用 note 去包就不用像上面一樣手動控制一個一個寫入,但要經過清洗
# 清洗資料 Strong Parameter:防止別人亂寫東西進來,可過濾掉不要的欄位,
# require輸入資料 permit欄位
clean_note = params.require(:note).permit(:title, :content)
# title: 是用來對應到資料表名稱
# @note 只是一個變數用來代替後面那串
@note = Note.new(clean_note)
# 如果存檔成功就把網址轉到/notes
if @note.save
redirect_to "/notes"
else
# 借views/notes/new.html.erb來畫出來給你看,不是重新讀取 new
# render 過程發現 @note 不是原本空空的 @note ,而是有帶了(clean_note)參數,
# 他會連同參數裡面的東西一起拿過來
# form_for 會再幫你塞回原本欄位,保留下來
render :new
end
end
# GET 顯示單一資料
def show
# 有要傳到其他方法或 view 就用實體變數
# find 找不到會噴錯 ActiveRecord::.....
# find_by 只會噴 nil
# 太複雜才會用SQL語法操作,避免 SQL injection
@note = Note.find(params[:id])
end
end
```
new.html.erb
```rb
<%# 用form_for 快速建立
根據@note的方法名去猜測,會幫你把路徑跟方法跟token都寫好
view 的角色是被動的,不要在這邊 new,controller 負責調度資料,流程控制,
在 controller new 之後再傳過來會比較好 %>
<%#form 小幫手%>
<%# 餵進來的東西如果有料會自動幫你帶入 %>
<%= form_for(@note) do |f|%>
<%= f.label :title, "標題" %>
<%= f.text_field :title %>
<%= f.label :content, "內文" %>
<%= f.text_area :content %>
<%= f.submit "送出" %>
<% end %>
```
show.html.erb
```rb
<h1>筆記: <%= @note.title %> </h1>
<p><%= @note.content %></p>
```
index.html.erb
```rb
<%# 最推薦寫法,叫做 view helper
全部包在 Ruby 內,link_to 是方法 新增筆記是引數,帶進去讓它顯示名字
new_note_path 也是引數,是要做的事 = 把路徑導向 /notes/new,亂打一通會顯示 Routing Error,裡面有寫
好處是寫錯會馬上噴錯(NameError) %>
<%# <%= link_to ("新增筆記", new_note_path) %>
<%= link_to "新增筆記", new_note_path %>
<%# 有加=會被印出 %>
<ul>
<%# 從index方法來的,@notes 是陣列因為是物件所以可以用方法 %>
<% @notes.each do |note| %>
<%#link_to note.title, note_path(note.id)%>
<%# link_to(note.title) ,link_to是方法,note.title是參數 %>
<%# link_to 呈現的資料,路徑:note_path跟id可不寫 %>
<li><%= link_to note.title, note_path(note) %></li>
<% end%>
</ul>
```
note.rb
```rb
class Note < ApplicationRecord
# 驗證交給model
# 有東西才給過
# validates = 類別方法 2 個參數,第二個是 hash
validates :title, presence: true
validates :content, presence: true
end
```
form.scss
```scss
// application.css 內不建議用 require_tree .,會按照英文字母順序載入,可能會被蓋掉
// require_tree . 可以把這個目錄的檔案都包起來
// require_self 寫在自己那邊也可
// application.css 入口打包擋
.field_with_errors {
display: inline-block;
label {
color: red;
}
input[type="text"],
textarea {
border: 1px solid red;
}
}
```
---
[Rails XMind](https://www.xmind.net/m/E4xCGw)
---
###### tags: `Ruby` `Rails`