3分鐘短文:Laravel路由加模型等於?

程式設計師小助手發表於2020-10-22

引言

上一章我們用3分鐘時間光速入門了laravel控制的用法,本章不準備說控制器了,說一說另外倆模組,就是路由Route和模型Model,這倆直接加起來,會有什麼奇思妙想的發生呢?

img

請大家接著往下看。

程式碼時間

還是最早我們講的那種方式,在路由地址上通過位置引數繫結,我們可以獲取到使用者輸入的資料。只不過,為了與模型檔案對應起來,可以直接在路由處理方法的閉包內呼叫模型方法,並組裝資料返回。

比如傳入id數值,返回查詢後的結果:

Route::get('conferences/{id}', function ($id) {
    $conference = Conference::findOrFail($id);
});

其中 findOrFail 方法是一個內建的語法糖,用於根據id查詢條目,找不到的丟擲404錯誤頁面。上面的路由也是很多地方都在用的通用的做法,可是程式設計師總是懶惰的,能少寫一行就少寫一行。laravel為我們準備了更多。

隱式繫結

首先來看一下預設的隱式路由模型繫結

什麼意思呢?就是路由內預設使用某個變數傳入引數,這個鍵名與執行方法變數名相同,那麼系統就會根據傳入的引數,在執行方法內使用依賴注入方式例項化一個模型,而例項化的方法,恰恰就是傳入的引數的查詢結果集

說了半天很繞對不對?看一個例子就明白了:

Route::get('conferences/{conference}', function (Conference $conference) {
    return view('conferences.show')->with('conference', $conference);
});

簡單地說,路由地址內的變數 {conference} 跟執行方法變數名 $conference 撞名了,這個時候系統就會想了,這是要用隱式的繫結模式啊。於是,把 {conference} 的值,作為查詢條件,使用執行方法內的模型 Conference 例項化並執行查詢結果,並賦值給 $conference 變數。

自定義鍵名

而路由內這個 {conference} 傳什麼數值呢?根據系統預設值,就是 ID。如果你不想用 ID,想用別的列欄位進行查詢,那也可以,比如這樣寫:

Route::get('conferences/{conference:title}', function (Conference $conference) {
    return view('conferences.show')->with('conference', $conference);
});

那麼例項化的時候,就認為這個位置引數傳的是 title 欄位用於查詢的條件。

懶人寫法

如果整個模型預設都不會用 id 這個欄位查詢,那麼在模型內過載實現下述方法即可:

public function getRouteKeyName()
{
    return 'title';
}

如果需要修改的路由模型繫結欄位太多,又不想挨個去寫模型檔案,可不可以集中起來管理呢?是可以的,在檔案 App\Providers\RouteServiceProvider 內手動追加類似以下程式碼:

public function boot(Router $router)
{
    parent::boot($router);
    $router->model('title', Conference::class);
}

在此處寫了,模型內就不用手動實現 getRouteKeyName 方法了。

寫在最後

本文講了一個再實際工程中用的甚至不是太多的一個功能——路由模型繫結,卻能為大家開啟思路提供很多幫助。

諸位還記得之前章節我們介紹的使用 slug 方式查詢資料集嗎?那正是典型的路由模型繫結。有興趣的同學可以往前翻一番圖文,或關鍵詞搜尋 slug 就可以愉快地延伸閱讀了。

Happy coding :-)

我是@程式設計師小助手,專注程式設計知識,圈子動態的IT領域原創作者

本作品採用《CC 協議》,轉載必須註明作者和本文連結
write-less-do-more-make-you-out-of-door

相關文章