如何将路由模型绑定查找数据从 id 更改为 slug

How to change Route Model Binding finding data from id to slug

我有如下路线。

Route::get('/articles/{articleSlug}' , 
    [App\Http\Controllers\ArticleController::class, 'single']);

single()ArticleController class 的方法在这里:

public function single($slug)
{
    $article = Article::where('slug',$slug)->first();
    $article->increment('viewCount');

    return view('home.article',compact('article'));
}

现在我希望使用路由模型绑定从 articles table 中基于列 slug 查找此数据。但是据我所知,Route Model Binding是根据id来查找数据的。那么如何仅针对 ArticleController.php 将路由模型绑定查找数据从 id 更改为 slug(这意味着其他控制器 classes 可以使用 id 作为路由模型绑定)?

你的控制器已经设置好了,你需要做的就是在路由中将你的变量名更改为$slug,我相信这就足够了:

Route::get('/articles/{slug}' , [App\Http\Controllers\ArticleController::class, 'single']);

将您的路线更改为:

Route::get('/articles/{article:slug}' , [App\Http\Controllers\ArticleController::class, 'single']);

然后将 Article 模型注入到您的控制器函数中,让 laravel 为您完成剩下的工作:

public function single(Article $article)
    {
        $article->increment('viewCount');
        return view('home.article',compact('article'));
    }

如果您想使用其他模型字段而不是 id 作为出价属性,您可以定义一个 getRouteKeyName,其中 return 必须使用的字段名称

class Article extends Model {
    // other methods goes here
    public function getRouteKeyName() {
        return 'slug';
    }
}

或者你可以这样定义路由的时候直接传字段名

Route::get('/articles/{article:slug}' , [App\Http\Controllers\ArticleController::class, 'single']);

在控制器中使用此代码,您必须确保在路由定义中作为参数提供的名称与 controller 参数的名称相匹配

public function single(Article $article)
{
    $article->increment('viewCount');

    return view('home.article',compact('article'));
}

您可以直接在路由定义中自定义路由模型绑定:

  1. 过去在 app/model/Article.php:

    中给出的代码

    public 函数 getRouteKeyName() { return 'slug'; }

2.when 你用 slug 改变路线到

 Route::get('/articles/{article:slug}' , [App\Http\Controllers\ArticleController::class, 'single']);
  1. 使用 id 示例将 slug 更改为 id

    Route::get('/articles/{article:id}' , [App\Http\Controllers\ArticleController::class, 'single']);

您可以像这样将绑定方法添加到您的模型 boot()

public function boot()
{
    Route::bind('article', function ($value) {
        return Article::where('slug', $value)->firstOrFail();
    });
 
}

要了解更多信息,请阅读 Laravel 文档中的这一部分 https://laravel.com/docs/9.x/routing#customizing-the-resolution-logic