61. 路由 路由模型繫結

weixin_33806914發表於2017-10-06
  • Laravel 為路由模型繫結提供了一個直接自動將模型例項注入到路由中的方法。

  • Laravel 會自動解析定義在路由或控制器行為中與型別提示的變數名匹配的路由段名稱的 Eloquent 模型。例如:

Route::get('api/users/{user}', function (App\User $user) {
    return $user->email;
});

在這個例子中,由於 $user 變數被型別提示為 Eloquent 模型 App\User,變數名稱又與 URI 中的 {user} 匹配,因此,Laravel 會自動注入與請求 URI 中傳入的 ID 匹配的使用者模型例項。如果在資料庫中找不到對應的模型例項,將會自動生成 404 異常。

  • 如果你想要模型繫結在檢索給定的模型類時使用除 id 之外的資料庫欄位,你可以在 Eloquent 模型上重寫 getRouteKeyName 方法:
/**
 * 為路由模型獲取鍵名。
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}

Route::get('/users/{user}', 'UsersController@show')->name('users.show');

...
use App\Models\User;
class UsersController extends Controller
{
    public function create()
    {
        return view('users.create');
    }
    public function show(User $user)
    {
        return view('users.show', compact('user'));
    }
}

在上面程式碼中,由於 show() 方法傳參時宣告瞭型別 —— Eloquent 模型 User,對應的變數名 $user 會匹配路由片段中的 {user},這樣,Laravel 會自動注入與請求 URI 中傳入的 ID 對應的使用者模型例項。

我們將使用者物件 $user 通過 compact 方法轉化為一個關聯陣列,並作為第二個引數傳遞給 view 方法,將資料與檢視進行繫結。

在檢視模板中就可以使用 {{ $user->name }} 顯示資料內容。


  • 要註冊顯式繫結,使用路由器的 model 方法來為給定引數指定類。在 RouteServiceProvider 類中的 boot 方法內定義這些顯式模型繫結:
public function boot()
{
    parent::boot();

    Route::model('user', App\User::class);
}

接著,定義一個包含 {user} 引數的路由:

Route::get('profile/{user}', function (App\User $user) {
    //
});

因為我們已經將所有 {user} 引數繫結至 App\User 模型,所以 User 例項將被注入該路由。例如,profile/1 的請求會注入資料庫中 ID 為 1 的 User 例項。

  • 如果你想要使用自定義的解析邏輯,就使用 Route::bind 方法。傳遞到 bind 方法的閉包會接受 URI 中大括號對應的值,並且返回你想要在該路由中注入的類的例項:
public function boot()
{
    parent::boot();

    Route::bind('user', function ($value) {
        return App\User::where('name', $value)->first();
    });
}

相關文章