# Ruby(05/14) 五倍紅寶石(第八屆共筆)(2021/8/09) [Gem套件](https://rubygems.org/?locale=zh-TW) 網址後面通常是 model 的名字 ## 資料庫關聯性 - 一對一:belong_to - 一對多:has_many - 多對一: - 多對多: --- ## migration 檔 遷移的意思,只是描述資料表的結構,記錄怎麼變大變小的,描述檔案連續的歷程紀錄 = 資料庫有版控紀錄。 會記錄在 schema.rb 檔案以及 sqlite3 的 schema_ 裏面。 db:migrate 用來掃還沒掃過的資料,每份資料只能被掃一次。 db:rollback 做逆向工程,讓他反向操作。 db:migrate前記得存擋,不然太快做會呈現不出來,如果前面被做過一次就無法在 migrate 第二次。 ### 壞掉怎辦: - 先把方法裡面的東西刪掉,使用 rollback 後再 migrate 一次。 - 大絕招:db:schema:load 根據schema.rb這個檔案,自動載入檔案,跳過錯誤,還原資料庫。 ### 撞名 model 名稱不能跟專案名稱、其他 model 或是保留字一樣。 ### Object-Relational Mapping(ORM) 物件關係對映 幫助使用者更簡便、安全的去從資料庫讀取資料,透過程式語言,去操作資料庫語言( SQL )。 將關聯式資料庫檔案對映到物件上。 --- ## 網路上的刪除不是刪除 有可能只是讓你看不見,但資料其實還在,可透過後台資料庫看到。 --- ## Evernote 專案 - title:string => 到資料庫會變成 varchar(1~?) - content:text => 到資料庫會變成 text(...~4G) 可放較多資料 - deleted:boolean default:false 只會知道有沒有被刪除 - add_index deleted_at:datetime 還會知道刪除時間 ### 建索引 類似書籍或字典的目錄,可快速找到需要的資訊。 建索引可加快搜尋資料的速度 => log(n) 常加在不好找的資料上面。 ### 語法 - rails c => irb - Note.all 的all = 類別方法 - command shift F 搜尋關鍵字 - rails routes:看到路徑對照表 路徑取名簡單明瞭即可,ex:/notes ### resources 創造的八條路徑,其中 PATCH 跟 PUT 合併在一起 要背,會由上往下找,對了就執行那個路徑。 - patch:只換掉其中一個資料 - put:整行換掉 ![](https://i.imgur.com/FGDdq4l.png) ### 命名慣例 統一一套規矩,Rails 可以讓每個人用相同邏輯命名,讓大家可用行話,比較好溝通。 - 列表習慣用複數 /members/2/edit - Resource 資源(有以下可用,總共有8種,可參照上圖): 筆記列表: GET /notes 看 3 號筆記: GET /notes/3 新增筆記:GET /notes/new 編輯 3 號筆記:GET /notes/3/edit resources :notes, {only: [:index, :show]}, 只開這幾條路的權限 {except 除了...其他都開} {} hash 可寫可不寫,通常會省略,要看的懂 實作時要先想好要開哪些權限,不要讓使用者自己新增更新等等。 - REST: 一種概念,RESTful API = 軟體建構風格,可參考維基 - 背起來: - get:取得頁面 - post:寫入資料庫裡面 - put:更新 - delete:刪除 ### 增加功能,追加路徑用do end member collection ```rb resources :notes, only: [:index, :show] do member do delete :cancel(概念上:改成 cancel 是取消的意思,不是刪除訂單) # 刪單一資源(路徑有id數字) # DELETE /orders/2/cancel end collection do delete :cancel # 全部資源(沒有id數字) # DELETE /orders/cancel end end ``` ### 雜 /notes/:id 的:是字串不是符號 瀏覽器只有支援 get post 其他都是用 post 來表達、模擬的 new 跟 create 是一組的,通常會搭配使用 ## 防止灌票 Rails 有預設機制,會檢查 post 行為是不是在我網頁輸入的,不是的話會擋下來。 => 沒有一樣的 token(令牌、代幣) 送不過來,要帶token過來 - authenrity_token:可以拿到整串 token ,但每次送表單時 Rails 都會產生隨機的 token,所以拿了也沒用。 - 資料庫寫的時區是標準時區 +0 時區 ### Routing Error 亂打一通會出現,因為沒有這個路徑 從 Routing Error 可以看到路徑對照表 如果/notes/亂打 ,會出現 show 錯誤是因為後面接的是:id,但他找不到這個 id 用/notes/new 不會出現 show 是因為 Rails 是由上往下找,先找到 new 就不會走到 show 了 - Note.new: 只會在記憶體裡,要用 .save 才能存進去資料庫。 - Note.create: 不用寫 save 可以直接存進去資料庫。 ![](https://i.imgur.com/moPWYtJ.png) ### params 是一個包含用戶所有傳進來的參數的Hash 在 controller 塞 debugger 可以用 params 印出 ![](https://i.imgur.com/Vq5koRS.png) ### 查看有無寫入資料庫 從 sqlite3 的 Browse Data 選你要看的資料表。 ### 實作 routes.rb ```rb Rails.application.routes.draw do # 創造一個 get "/hello", to: "pages#main" 可以連到/hello頁面 # 名字要對的起來 # get "/notes", to: "notes#index" # get "/notes/new", to: "notes#new" # resources 直接生8條路徑,不用像上面一樣一個一個慢慢寫 resources :notes # 萬一要改網頁路徑名要怎辦? # 用 path:"articles"可以直接改網頁路徑名,網址從/notes變成/articles # resources :notes, path:"articles" end ``` index.html.erb ```rb <h1> 筆記列表 </h1> <%# <a href="/notes/new">新增筆記</a> <%= link_to "新增筆記", "/notes/new" %> <%# 最推薦寫法,叫做 view helper 全部包在 Ruby 內,link_to 是方法 新增筆記是引數,帶進去讓它顯示名字 new_note_path 也是引數,是要做的事 = 把路徑導向 /notes/new, 亂打一通會顯示 Routing Error,裡面有寫 好處是寫錯會馬上噴錯(NameError) %> <%# <%= link_to ("新增筆記", new_note_path) %> <%= link_to "新增筆記", new_note_path %> <%# 完整路徑 %> <%# <%= link_to "新增筆記", new_note_url %> ``` new.html.erb ```rb <h1>新增筆記</h1> <%# action:往哪送,method: 使用什麼方法,get or post 沒寫就是 get,後端只在乎 name %> <%# <form action="/notes" method= "POST"></form> %> <%# 用form_for 快速建立 根據@note的方法名去猜測,會幫你把路徑跟方法跟token都寫好 view 的角色是被動的,不要在這邊 new,controller 負責調度資料,流程控制, 在 controller new 之後再傳過來會比較好 %> <%= form_for(@note) do %> <%# name 後面接的名稱要跟後端資料庫建的資料表欄位名稱一樣才能送過去 %> <%# 資料表欄位名稱如果忘記可以去 db/migrate 裡面的檔案看他的描述 %> 標題:<input type="text" name="title"> 內文:<textarea name="content"></textarea> <input type="submit" value="送出"> <% end %> <%# QueryString https://google.com/?p=輸入表格內的東西 & 下一組 %> ``` notes_controller.rb ```rb class NotesController < ApplicationController def index end def new # 用 Note.new 做出一個新的 model ,生一個 @note 實體出來,用 @note 才能把值帶到別的檔案 # model 用來放資料庫相關資料,Note 是從 model 來的,裡面有一個 class 叫做 model # controller 用來產生物件及資料運算,所以@note = Note.new 會放這邊 @note = Note.new end def create # 安插 debugger + 輸入 params 可以印出包含用戶所有傳進來的參數的 hash # 要印出 hash 可以用 [ ] 裡面放符號或字串都行, # 為何字串也行是因為 Rails使用到 HashWithIndifferentAccess 這個類別做出來的 # 而我想找出用戶傳進來的內容所以才這樣寫 title = params[:title] content = params[:content] # title:、content:是用來對應到資料表名稱,才能取到裡面值, # 先修教材的 candidate 已經指定好 table 欄位名稱,不用再設定title:、content: # note 只是一個變數用來代替後面那串 note = Note.new(title: title, content: content) # 如果存檔成功就把網址轉到/notes if note.save redirect_to "/notes" else end end end ``` --- ###### tags: `Ruby` `Rails`