Laravel 5.6 — привязка модели маршрута с контроллером по умолчанию

Я создаю приложение для шоппинга с использованием Laravel, где URL каждого продукта должен быть кратким.

Вместо использования следующей структуры постоянных ссылок: (что является распространенным, но неблагоприятным)

www.example.com/products/{product-slug}

Я хочу использовать эту структуру постоянных ссылок:

www.example.com/{product-slug}


Для этого я использую неявную привязку модели маршрута в моем файле маршрутов:

Route::get( '{product}', function ( App\Product $product ) {

return view( 'product' ); // this works, but is not what I want

});

И я переопределяю поведение поиска в моем Product модель:

class Product extends Model
{

public function getRouteKeyName()
{
return 'slug'; // use the 'product.slug' column for look ups within the database
}

}

Теперь, согласно документации Laravel:

Laravel автоматически разрешает модели Eloquent, определенные в маршрутах или действиях контроллера, чьи имена переменных с подсказками типов соответствуют имени сегмента маршрута.
(Просмотреть исходный код)

Так что я знаю, что Laravel будет соответствовать {product} переменная для продукта, хранящегося в моей базе данных, или возврат 404 ответа, если он не найден.

И все это имеет смысл для меня …


Тем не мение…

Каждая страница продукта уникальна, поэтому после того, как маршрут соответствует {product}, тот {product} объект необходимо передать контроллеру для дальнейшей обработки.

Итак, как мне передать этот маршрут контроллеру, если я хочу сохранить неявную привязку модели?

0

Решение

Укажите маршрут к функции контроллера.

Это будет ваш маршрут (я назвал контроллер ProductController и указал на это show функция, но вы можете переименовать оба по своему вкусу):

Route::get( '{product}', 'ProductController@show');

И это будет в вашем ProductController:

public function show(Request $request, \App\Product $product)
{
// Do stuff with $product

// Return view and pass it the $product variable
return view('product', compact('product'));
}
3

Другие решения

Чтобы ответить на мой собственный вопрос, я думаю, что нашел отличное решение, которое сочетает в себе мой первоначальный подход и devk-х ответ:

Кредиты для Блог Арджуна для идеи.

Как оказалось, вы также можете выполнить неявное связывание модели в контроллере, передав модель Eloquent в качестве зависимости:

/* App/Http/Controllers/ProductController.php */

/**
* Get the Product object.
*
* @param App\Models\Product
*/
public function show( Product $product )
{
return view( 'product', compact( 'product' ) );
}

Несмотря на то, что мы сейчас ссылаемся на модель с помощью контроллера, Laravel все равно автоматически разрешит модель. На самом деле, это поведение четко определено в документации:

Laravel автоматически разрешает модели Eloquent, определенные в маршрутах или же
действия контроллера
чьи имена переменных с подсказкой типа соответствуют маршруту
имя сегмента.
(Просмотреть исходный код)

Должно быть, я пропустил эти слова, когда я прочитал это в первый раз …


Теперь, чтобы настроить {product-slug} маршрут (так, как я хотел), вы должны настроить свою модель и определения маршрута следующим образом:

/* App/Models/Product.php */

class Product extends Model
{
/**
* Get the route key for the model.
*
* @return string
*/
public function getRouteKeyName()
{
return 'slug';
}
}

Как упоминалось ранее, переопределение getRouteKeyName() метод заставит Laravel искать продукт, используя его slug столбец в базе данных вместо его id столбец (который по умолчанию).

/* routes/web.php */

Route::get( '{product}', 'ProductController@show' );

В нашем файле маршрутов мы все еще называем наш параметр {product} (вместо {product-slug}) потому что имя параметра должно совпадать с именем модели Eloquent.


Используя эту конфигурацию, запросы делаются на:

www.example.com/{product-slug}

вернет страницу товара, если {product-slug} соответствует одному, хранящемуся в базе данных. Если продукт не найден, вместо него будет возвращен ответ 404 Not Found.

Однако, поскольку мы связываем этот маршрут с базовым путем /это означает, что каждый URL, запрошенный клиентом, будет проходить через эту конфигурацию.

Чтобы избежать этой проблемы, убедитесь, что определения вашего маршрута находятся в правильном порядке в вашем файле маршрутов (от наибольшего до наименьшего приоритета), и используйте проверку при возникновении конфликтов.

-1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector