Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Всем привет
У меня возникла проблема с ЧПУ.
Дело такое, создал бд и в ней таблицу с товарами, в ней есть поле алиас типа varchar(255) и принимает только уникальные значения, и вот, я хотел бы чтоб значение этого поля выводилось в адресные строке например:http://laravelshop/product/mujskie_chasu_quarc, где 'mujskie_chasu_quarc' это значение поля алиас.
Ссилка на маршрут:
<a href="{{ route('product',['product_alias' => $product->alias])}}">
Маршрут:
Route::match(['get'],'product/{product_alias}',['uses'=>'ProductController@index','as'=>'product'])->where('product_alias','[\w-]+');
Controller:
public function index($product_alias)
{
$products = Product::where('id','=',$id)->get();
return view('site.product',compact(''products'));
}
Так вот, все работает если значение алиаса короткое, если оно длинное то ЧПУ виводит, но виборку з таблици не проесходить и возникает ошибка:NotFoundHttpException
Не в сети
// Модель product
public function setAliasAttribute($value)
{
$this->attributes['alias'] = str_slug($value);
}
public function scopeFindByAlias($q, $alias)
{
return $q->whereAlias($alias)->first();
}
public function index($alias)
{
$products = Product::findByAlias($alias);
return view('site.product',compact(''products'));
}
Не в сети
return $q->whereAlias($alias)->first();
во-первых тут я бы написал firstOrFail() – тогда 404 на несуществующих в базе продуктах будет генерироваться автоматически, во-вторых изобретать скоупы только для того чтобы выбирать каким-то способом модели в маршрутах – это по-моему излишне, есть Route::model для автоматического резолва айдишника в модель, есть на моделях getRouteKey() который по умолчанию возвращает $primaryKey то есть 'id', но его можно переопределить на что угодно, например 'alias'.
тогда пример будет выглядеть так
модель:
public function setAliasAttribute($value)
{
$this->attributes['alias'] = str_slug($value);
}
public function getRouteKey()
{
return 'alias';
}
в маршрутах:
Route::model('product', App\Product::class);
Route::get('product/{product}', ['uses'=>'ProductController@index','as'=>'product']);
в контроллере:
public function index(App\Product $product)
{
return view('site.product', compact('product'));
}
генерация ссылок:
<a href="{{ route('site.product', $product) }}"></a>
всё. осталось только не забыть добавить в таблице products индекс по полю alias – запросов по нему видимо будет много. и видимо индекс должен быть unique, хотя при использовании soft-deletes может быть и нет, надо смотреть по обстоятельствам…
ps. писал по памяти, не обессудьте если где что перепутал
Не в сети
- во-первых тут я бы написал firstOrFail
Согласен. В живом проекте у самого firstOrFail(), тут почему то first() написал:|
- во-вторых изобретать скоупы только для того чтобы выбирать каким-то способом модели в маршрутах – это по-моему излишне
Всегда так делал, н когда с этим проблем не возникало.
Изменено TrueKanonir (26.08.2017 20:24:37)
Не в сети
Страницы 1