前面課程已經知道如何新增/製作列表
首先,我們進到view/index.html.erb
將原本在 table 裡面 Action 選項的<td>
裡面換成 update
,但是我們要使用link_to的方法來寫。
所以要先去找門口阿姨(Routes)才能知道正確的路徑。
打開終端機輸入rails routes
,可以找到那8個路徑中,跟edit
有相關的。找到了,所以我們可以拿前面的prefix verb
來用在link_to裡面。
因為這個路徑也是需要有一個id
所以寫法跟上面的Name
欄位很像。path後面接id
。edit_candidate_path(cadidtae.id)
打開瀏覽器看看,確實看到Action``Update
欄位的出現
也就是對應每個候選人 id 在Action欄位新增一個叫做 update 的超連按鈕,點擊之後會連到另外一個頁面。
點擊第一位候選人的update按鈕,會看到提示畫面。沒有在controller中找到叫做edit
的 action。
但這時我們可以注意網址列的部分,有看到第一位候選人的 id 有在網址列上,表示目前是正確的。
接著我們就要到CandidatesController
中產生對應的edit action
可以預期的是,重新整理瀏覽器後,頁面應該會顯示沒有 edit 的 template。
當然我們也就必須到 view 裡面 新增對應的edit.html.erb
檔案。先給它一個<h1>Edit Candidate</h1>
再確認一下瀏覽器是否可以正常顯示頁面,確實有正確顯示網址列也看到h1
標籤
這時候我們想要在畫面上給它一個表單(form),因為其實表單的內容應該會跟新增候選人頁面的表單差不多,一樣有名稱、年紀、政見的等欄位。
所以編輯候選人頁面中的表單,我們可以稍微偷懶一點點,借用原本new.html.erb
的內容 copy & past。
再打開瀏覽器確認畫面如何,發現咦?還是有錯誤訊息。
為什麼會看到錯誤訊息呢?會看到是正常的,我們回到CandidatesController
來看裡面的edit action
。
這時候edit action
都沒有做任何事,所以剛剛看才會看到錯誤訊息。
這時候我們可以再借用show action
裡面的變數@candidate = Candidate.fint_by(id: params[:id])
放到edit action
裡面。
因為show action
可以去抓到某個id
候選人的資料,這邊在edit action
裡面也是要針對某個id
候選人的資料做編輯。所以直接把整行code借用過來。
接著我們再打開瀏覽器確認畫面
此時神奇的事情發生了,可以發現畫面已經做好了。
這也是form_for()
這個小幫手厲害的地方,它發現參數@candidate
是「有料的」,所以把裡面的「料」一個一個往每個欄位塞。
這時候我們可以再打開網頁原始碼,來看一下裡面的<form>
標籤。
可以跟之前做新增的時候對比一下,可以明顯發現有不一樣。edit
方法會帶到id
,把id
帶進來。發法也是用「POST」,但是往後繼續看,會看到一個隱藏input
欄位,它的名字叫"_method"
,value="PATCH"
。
這時候我們可以打開終端機的Routes
,來看一下patch方法對/candidates/id 這個位址送資料的話,對應的controller action
是candidate#update
。也就表示我們按下送出後,他會直接往update action
這個地方去。
是不是覺得form_for()
很厲害了,我們只是把完全同樣的code從new.html.erb
檔案直接複製過來edit.html.erb
。完全沒有去修改任何的code,它還可以猜到我們要做什麼事情。
因為form_for()
會去猜,你既然從資料庫裡面撈東西出來,應該不會是要新增才對,所以會猜到你可能是要去修改資料。
在我們沒有更改原始碼的情況下,可以發現原本在新增候選人頁面的按鈕是new candidate
。
而目前的頁面顯示的是 update candidate
。form_for()
直接幫我們做好了。
點擊update candidate
按鈕送出資料,看看瀏覽器的頁面如何。馬上看到提示訊息。
就如同之前的步驟,找不到某個action
,那就動手做給你。
這時我們可以觀察終端機的(Routes),路徑/candidates/:id(.:format)
有出現4個一樣的路徑。但是使用的方法卻不同。表示不一樣的動作,對應不同的controller action
。
- GET: 讀取候選人資料
- PATCH:更新候選人資料
- PUT:更新候選人資料
- DELETE:刪除後選人資料
所以我們就可以知道按下頁面的update candidate
按鈕,應該是會往candidates#update
這個地方去找。
接著就是要到CandidatesContrller
裡面新增update action
。
因為 「HTTP不會有狀態」,瀏覽器頁面跳轉的時候,資料不會保留,現在唯一有的是網址列的id
及剛剛在編輯候選人頁面,我們輸入在表單裡面的那包資料。
所以在CandidatesController
的update action
我們要再重新抓一次資料,並且更新抓到的那包資料。
而更新資料的動作會跟在新增候選人時的動作很相似。所以code寫法很像。
新增時,先新增一個物件,如果新增成功就接著往下個目的地走,如果新增失敗就重新 Render 畫面。
而我們在update action
也是做類似的事情。
但此時在update action
要記得做資料「清洗」,因為我們之前有定義了private method
,已經有一包清洗過的資料,可以把它拿到update action
來使用,所以要將 code 寫成
如果成功更新,畫面會跳出訊息顯示候選人更新成功!!!並且將頁面跳轉到候選人清單頁面。
打開瀏覽器確認,確實跟我們預期的一樣。
如果更新候選人資料失敗,那就是借用edit.html.erb
這個檔案,重新渲染畫面。
候選人更新的部分就到這邊,下堂課要介紹”刪除”功能
參考來源:為你自己學 Ruby on Rails (https://railsbook.tw/)