如何在laravel 8中使用slug代替id
这是我在控制器
中的公共函数public function singleProduct($slug){
$product = Product::findOrFail($slug);
return view('frontend.product.product', compact('product'));
}
这是路由
Route::get('/product/{slug}', [HomeController::class, 'singleProduct']);
,这是从它将到单个产品的地方
<a href="{{ url('/product/'.$product->slug) }}" class="customBtn4">Read More</a>
如果你想在不改变数据库表的主键的情况下使用slug来绑定路由模型,Laravel提供了一个方法来覆盖用于路由模型绑定请求的键。所以你可以把这个添加到你的模型中:
public function getRouteKeyName()
{
return 'slug';
}
可以这样使用:
public function singleProduct(Product $product)
{
return view('frontend.product.product', compact('product'));
}
//
Route::get('/product/{product}', [HomeController::class, 'singleProduct']);
然而,这会改变每个路由/请求的路由键,这可能不是你真正想要的。因此,更简单的方法是直接在路由上指定模型键,像这样:
Route::get('/product/{product:slug}', [HomeController::class, 'singleProduct']);
这也允许你在你的控制器中使用它而不需要额外的查询:
public function singleProduct(Product $product)
//...
Laravel已经提供了一个使用模型类中的$primaryKey
属性显式设置主键的选项,您可以将另一列设置为主键,而不是默认的id
列。更多信息:https://laravel.com/docs/8.x/eloquent#primary-keys
现在使用slug
而不是id
作为默认路由路径,请遵循以下步骤:
步骤1:打开Product.php
模型文件并设置$primaryKey
,$incrementing
和$keyType
属性:
class Product extends Model
{
protected $primaryKey = 'slug'; // your column name
public $incrementing = false;
protected $keyType = 'string';
...
步骤2:在HomeController.php
控制器文件中编辑singleProduct
方法:
public function singleProduct(Product $product)
{
return view('frontend.product.product', compact('product'));
}
。现在,您不需要首先找到弹头并检查它是否存在。Laravel会自动完成。
删除产品前的"/"
<a href="{{ url('/product/'.$product->slug) }}" class="customBtn4">Read More</a>
所以应该是这样的:
<a href="{{ url('product/'.$product->slug) }}" class="customBtn4">Read More</a>
如果您希望使用id以外的列来解析Eloquent模型,您可以在路由参数定义中指定该列。
Route::get('/product/{product:slug}', [HomeController::class, 'single_product']);
inroutes/web.php
:
use AppHttpControllersHomeController;
use AppModelsProduct;
// Route definition...
Route::get('/product/{product:slug}', [HomeController::class, 'single_product']);
inHomeController
:
// Controller method definition...
public function singleProduct(Product $product)
{
return view('frontend.product.product', ['product' => $product]);
}