---
# System prepended metadata

title: Ruby(06/14) 五倍紅寶石(第八屆共筆)(2021/8/10)
tags: [Rails, Ruby]

---

# 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`