10. Обновление и изменение категорий
19 Июня 2020 02:02 (Редактировано: 21 Июня 2020 04:08)
За обновление информации в категоирях в админке будет отвечать метод update
в контроллере CategoryController
. Путь: project.loc\app\Http\Controllers\Blog\Admin\CategoryController.php
.
Этот контроллер будет выполняться при нажатии на кнопку "Сохранить" на странице редактирования категории в админке. Естественно, мы пропишем это.
Наполняем метод update
следующим содержимым:
public function update(Request $request, $id)
{
$item = BlogCategory::find($id);
if(empty($item)) {
return back()->withErrors(['msg' => "Запись id=[{$id}] не найдена"])->withInput();
}
$data = $request->all();
$result = $item->fill($data)->save();
if($result) {
return redirect()->route('blog.admin.categories.edit', $item->id)->with(['success' => 'Успешно сохранено']);
}else{
return back()->withErrors(['msg' => 'ошибка сохранения'])->withInput();
}
}
По порядку:
- 1 строка. Передаем первым параметром в метод объект класса Request. Этот объект предназначен для работы с входящими данными. В нем содержится разная инфа о типах запроса (ajax/не ajax), ip адрес и многое другое...
- 1 строка. Передаем вторым параметром id категории. По этому идентификатору будет строиться маршрут для обновления данных, в маршрутах он выглядит так:
| | PUT|PATCH | admin/blog/categories/{category} | blog.admin.categories.update | App\Http\Controllers\Blog\Admin\CategoryController@update
В файле представления
edit.blade.php
в блоке формы мы, также, передаем директиву, что это метод PATCH для Laravel. -
3 - 6 строки. Используем метод find для поиска в базе категории с переданным идентификатором, если такая есть - вернется объект класса
BlogCategory
, если нет -null
; Поэтому если срабатывает empty мы переадресуем посетителя на предыдущю страницу (там где была нажата кнопка) с передачей информации об ошибке с помощью методаwithErrors
c текстом ошибки и методаwithInputs
, чтобы те данные, которые уже были введены в форму не пропали после редиректа и вернулись, а уже в представлении можно вывести проверку на то были ли возвращены такие данные. Таким образом, при ошибке все, что было введено в форму - останется. Поэтому вносим поправки в файл item_edit_main_col.blade.php в самый низ где textarea формы и придаем ей следующий вид:<textarea name="description" id="description" rows="3" class="form-control"> {{old('description', $item->description)}} </textarea>
С помощью хелперской функции old мы говорим какой ключ искать в старом инпуте если он придет. Если ключ не найден или не пришли данные то мы подставляем данные старые из базы данных.
Можно по эксперементировать и попробовать убрать withInput и посмотреть что будет происходить. Также можно посмотреть результат в дебагбаре
- 8 строка. Получаем все из объекта
Request
с помощью методаall()
. Также есть методinput()
, который, вероятно, получает только значения полей формы. - 9 строка. У объекта
BlogCategory
есть унаследованный отModel
методfill()
, который заполнит объект данными и методомsave()
запишет их в базу. А ответ будет true/false, который будет положен в переменную$result
. Чуть дальше заполнимBlogCategory
данными, взаимодействующими с этим методом. - 10 - 15 строки. Поведение в зависимости от того, что в
$result
.- Если
true
- шлем по маршруту с с сообщениемsuccess
с помощью хелперской функцииredirect()
. - Если
false
- возвращаем на предыдущую страницу с сообщением об ошибке и возвращением значений инпутов с помощью хелперской функцииback()
.
- Если
Обновляем класс BlogCategory
Путь: poligon.local\app\Models\BlogCategory.php
.
<?php
namespace App\Models;
use Eloquent;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* BlogCategory
*
* @mixin Eloquent
*/
class BlogCategory extends Model
{
use SoftDeletes;
protected $fillable = ['title', 'slug', 'parent_id', 'description'];
}
- 7 строка. Добавляем SoftDeletes;
- 17 строка. Подключаем SoftDeletes.
- 19 строка. Добавляем свойство $fillable, которое обозначит с какими полями работать. то есть, с помощью метода fill в CategoryController(метод update) будут сохранены только указанные поля.
Примечание. Это также необходимо в целях безопасности, чтобы злоумышленник не мог передать что-либо помимо этих полей
Внесение правок в директории
- Переименовываем директорию
project.loc\resources\views\blog\admin\category
вcategories
. Полный путь должен выглядеть вот так:project.loc\resources\views\blog\admin\categories
. - Переименовываем подключаемые файлы в представлении в
project.loc\resources\views\blog\admin\categories\edit.blade.php
. Там два include, у которых в путиcategory
, переделываем вcategories
соответственно. - Переименовываем в файле
poligon.local\app\Http\Controllers\Blog\Admin\CategoryController.php
в методеedit()
путь возвращаемого представления с category на categories. Также смотрим методindex()
который нам выводит список категорий, в нем тоже меняем возвращаемое представление с category на categories.
Проверяем, чтобы все работало!
Добавляем сообщения об ошибке в представление
Путь: poligon.local\resources\views\blog\admin\categories\edit.blade.php
.
@extends('layouts.app')
@section('content')
@php /** @var \App\Models\BlogCategory $item */ @endphp
<form method="POST" action="{{ route('blog.admin.categories.update', $item->id) }}">
@method('PATCH')
@csrf
<div class="container">
@php
/** @var \Illuminate\Support\ViewErrorBag $errors */
@endphp
@if($errors->any())
<div class="row justify-content-center">
<div class="col-md-11">
<div class="alert alert-danger" role="alert">
<button class="close" type="button" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">x</span>
</button>
{{ $errors->first() }}
</div>
</div>
</div>
@endif
@if(session('success'))
<div class="row justify-content-center">
<div class="col-md-11">
<div class="alert alert-success" role="alert">
<button class="close" type="button" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">x</span>
</button>
{{ session()->get('success') }}
</div>
</div>
</div>
@endif
<div class="row justify-content-center">
<div class="col-md-8">
@include('blog.admin.categories.includes.item_edit_main_col')
</div>
<div class="cl-md-3">
@include('blog.admin.categories.includes.item_edit_add_col')
</div>
</div>
</div>
</form>
@endsection
Изменения, которые мы добавили - это код с 9 - 36 строчки.
В этих строках, в зависимости от результата, будет формироваться сообщение об успешном сохранении или о наличии ошибки.
- 9 - 11 строки. Прописываем директиву для PHPStorm, чтобы он подсказывал методы для $errors, которые он берет из указанного файла.
- 12 - 13 строки. Блок с ошибкой.
- 19 строка. Берем только первую ошибку т.к. в нашем случае ошибка может быть только одна - найден/не найден id ресурса.
- 25 - 36 строки. Блок с подтверждением.
- 32 строка. Через сессию получаем код ответа. Laravel такие коды передает через сессию.
На этом, работа с обновлением категорий закончена.
Примечание. Автор курса отмечает, что большая часть написанного кода - говнокод, который в последующем будет исправляться. Цель такого подхода - понимание того, как стоит писать в Laravel, а как нет!