Laravel 學習筆記 — 專案練習 Part 3 — 新增文章

ViNciHsu
Oct 18, 2020

--

現在,想要在首頁的文章列表,增加一個連結,連結到"新增文章"的頁面;為何 <a> 標籤的路徑要連到 create 呢?因為前面 ArticlesController 是用 resource 創建的,預設的幾個 function 名稱() 是固定的,包含了 store()/index()/create()/destroy/update/show/edit

article.create 是用 GET 來處理,但送出之後,就會使用 POST ,到 article.store 來處理後續

原本<a>的路徑寫法

改用 name route 的寫法寫 <a> 的路徑,這樣如果之後要改路徑的話,只要到 web.php 修改,全站的連結都可以跟著改,較為方便

改用 route 來寫 <a> 連結

接著到 ArticleController.php 編寫 create() 相關內容,設定 return view 為哪個頁面

編寫 create() 相關內容

可預期的,因為還沒有建 view 的 blade 頁面,因此會產生錯誤訊息;因此到 resources\views\articles\ 建立create.blade.php,編寫和 index.blade.php 相似的內容,即可

create.blade.php 內容

緊接著,要在"文章 > 新增文章"這個頁面,做一個表單(form),在表單送出後,會透過 ORM 寫進資料庫

此處建立一個 <form> ,要送出表單要使用 POST,因此 action 的內容要使其送到 articles.store 去做處理

截至目前的畫面

但按下"新增文章"的按鈕後,還不會新增成功,因為 ArticleController.php 還未增加 function store() 的內容

另外注意,如果送出後出現的是 PAGE EXPIRED,乃是因為Laravel 有個保護機制,就是如果使用 post 送出資料出去後,並未放置適當的 Token 的話,就會提醒你說,該頁面過期了,主要是防止 CSRF (跨站請求偽造)這種攻擊手法

PAGE EXPIRED
加上 @csrf

在加上 CSRF 的保護機制後,可以查看網頁出現了隱藏的欄位 name="_token",紀錄了 Token,該 value 是隨機生成的

由於還未建立 function store() ,因此出現相關錯誤訊息

編寫 function store() 和其他 index() / create() 不一樣的地方是, store() 不需要像其他 function ,需要將畫面渲染出來,因此不需要 return view() ,只需要將 post 送出來的資料做處理後即可

store() 因為要接收前端傳來的資料,因此需要使用 Request

而 validate() 這個方法,則是可以協助驗證填寫欄位時,是否符合開發人員定的規則

store(Request $request) 中,要新增文章是需要先行登入才能發表的,因此需要撈使用者相關資料,但是截至目前為止,我們還未將 App\Models\User.php 做關聯性,因此先來做關聯性

寫個一對多的 function,因為一個使用者可以發表很多文章

寫個一對多的 function

反過來,在 App\Models\Article.php,也需要有相對應的內容,每個 article 都會有一個 user,因此此處對應是用 belongsTo()

每個 article 都會有一個 user

回到 ArticlesController.php 將 store(Request $request) 寫完

試做到目前為止能否成功新增文章;輸入文標題與內文後,送出,發現出現以下錯誤訊息:Call to a member function articles() on null

使用 dd(auth()->user()) 檢查後發現,因為目前不在登入狀態,引此只得到空值

回到 localhost:8000/login 重新登入後,再使用 dd(auth()->user()) 就能查到使用者資料了

使用 dd 來了解目前得到哪些資料

重新做一次新增,發現仍有錯誤,意思是,無法批次大量寫入,需要到 App\Models\Article 新增 $fillable 相關內容

重新覆寫 $fillable,再次新增,發現依然跳出錯誤

重新覆寫 $fillable

此時仍然有錯誤,因為我們做 migration 時,忘了給 state 預設值

重新覆寫 $fillable,仍有錯誤
忘了給 state 預設值

切記,正常流程應該要新作一個 migration,但是此為練習專案,且目前資料庫都沒有資料,可以斟酌使用 php artisan migrate:rollback

php artisan migrate:rollback

重新給 state 預設值為 draft,這樣所有文章在發布時,預設都是 draft,即所有文章在不指定的狀態下,都屬於草稿階段(draft)

重新給 state 預設值為 draft

修改好資料表結構後,執行 php artisan migrate;要記得,rollback 再重作不是一個好做法,此處是因為這個 table 目前沒跟別人共用,且尚未有任何資料存在,勉強補救的作法

修改好資料表結構後,執行 php artisan migrate

目前可以試試看,再重新新增一篇文章能否成功,也有寫入 user_id

到 SQLite 確認,成功新增了一篇文章

由於剛剛點下"新增文章"的按鈕後,就直接跳轉到首頁了,因此我們試著增加一點東西,讓我們在點下按鈕後,給我們一些提示訊息

我們到 ArticleController.php 內 store() 的最後,導向首頁時,加上 with() 並給予要提示的訊息

加上 with() 並給予要提示的訊息

with() 的做法其實是在 sessions 內偷塞一些東西,而由於通知在全站都很常用到,因此我們可以把這些通知放到 layouts 來使用

我們將剛才的通知放到 resources\views\layouts\article.blade.php 內,用 @if 來判斷 session() 是否有拿到 notice 相關內容,有的話就顯示個快閃訊息,這個訊息顯示過會消失(重新整理後就會不見)

用 blade 的 if 來判斷 session() 是否有拿到 notice 相關內容

文章新增成功出現的快閃訊息;雖然文章的 list 還未做,但是目前能讓我們了解我們做對那些事情

出現設置好的快閃訊息

--

--

No responses yet