9. Страница редактирования категорий. Админка

08 Июня 2020 01:10 (Редактировано: 08 Июня 2020 03:01)

Работать будем с методом edit в контроллере категорий CategoryController.php.

Формируем метод edit

Приводим метод edit к следующему виду:

/**
 * Show the form for editing the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function edit($id)
{
    $item = BlogCategory::findOrFail($id);
    $categoryList = BlogCategory::all();

    return view('blog.admin.category.edit',
           compact('item', 'categoryList'));
}

Тут мы передаем в метод findOrFail идентификатор ресурса для редактирования. Принцип работы этго метода в том, что он либо делает выборку из БД и возвращает данные, либо если данных нет - возвращает 404. Крайне рекомендуется использовать этот метод только в случаях работы с одной какой то сущностью. Если мы будем делать много выборок через этот метод, то ошибка в одной из них будет приводить к прекращению работы всего скрипта и возвращению 404.

Также существует метод find и много других sql-подобных методов, которые вернут нам выборку либо же пустой результат, но конкретно сейчас используем findOrFail.

Создание верстки для редактирования

Создаем файл-шаблон для редактирования по следующем адресу project.loc\resources\views\blog\admin\category\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">
            <div class="row justify-content-center">
                <div class="col-md-8">
                    @include('blog.admin.category.includes.item_edit_main_col')
                </div>
                <div class="cl-md-3">
                    @include('blog.admin.category.includes.item_edit_add_col')
                </div>
            </div>
        </div>
    </form>
@endsection

Здесь, как и в других шаблонах: берем за основу layouts.app, определяем верстку, которая попадет в секцию content и через комментарий php говорим PHPStorm использовать для item объект BlogCategory. 

Основные действия

  • Строка 5. В action формы помещаем функцию построения маршрута для сохранения категории;
  • Строка 6. Такой конструкцией @method('PATCH') мы говорим laravel использовать метод PATCH для запросов т.к. в html-формах может быть только GET или POST, а PATCH - это элемент архитектурного стиля REST, но если не указать это то laravel будет пробовать искать blog.admin.categories.update для GET или POST и, естественно, не найдет и вернет ошибку. Можно посмотреть список маршрутов и убедиться в том, что маршурут blog.admin.categories.update обрабатывается PUT | PATCH.
  • Строка 7. Директива @crsv для защиты формы от различного рода хакерских атак.
  • Строки 11 и 14. Подключаем отдельные файлы шаблонов для ээлементов формы. Создадим их позже...

Создание шаблонов для элементов формы

Речь идет о шаблонах, рассмотренных выше:

  1. includes.item_edit_main_col
  2. includes.item_edit_add_col

Примечание. В шаблонах не пишутся окончания типа .blade.php. Laravel их дописывает сам при обработке.

includes.item_edit_main_col

Полный путь для файла: project.loc\resources\views\blog\admin\category\includes\item_edit_main_col.blade.php. Наполняем его:

@php /** @var \App\Models\BlogCategory $item */ @endphp
<div class="row justify-content-center">
    <div class="col-md-12">
        <div class="card">
            <div class="card-body">
                <div class="card-title"></div>
                <ul class="nav nav-tabs" role="tablist">
                    <li class="nav-item">
                        <a href="#maindata" class="nav-link active" data-toggle="tab" role=""tab>Основные данные</a>
                    </li>
                </ul>
                <br>
                <div class="tab-content">
                    <div class="tab-pane active" id="maindata" role=""tabpanel>
                        <div class="form-group">
                            <label for="title">Заголовок</label>
                            <input type="text" name="title" value="{{ $item->title }}" id="title" class="form-control" minlength="3" required>
                        </div>
                        <div class="form-group">
                            <label for="slug">Идентификатор</label>
                            <input type="text" name="slug" value="{{ $item->slug }}" class="form-control" id="slug">
                        </div>
                        <div class="form-group">
                            <label for="parent_id">Родитель</label>
                            <select name="parent_id" id="parent_id" class="form-control" placeholder="Выберите категорию" required>
                                @foreach($categoryList as $categoryOption)
                                    <option value="{{ $categoryOption->id }}" @if($categoryOption->id == $item->parent_id) selected @endif>
                                        {{ $categoryOption->id }}. {{ $categoryOption->title }}
                                    </option>
                                @endforeach
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="description">Описание</label>
                            <textarea name="description" id="description" rows="3" class="form-control">
                                {{ $item->description }}
                            </textarea>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

includes.item_edit_add_col

Полный путь для файла: project.loc\resources\views\blog\admin\category\includes\item_edit_add_col.blade.php. Наполняем его:

@php /** @var \App\Models\BlogCategory $item */ @endphp
<div class="row justify-content-center">
    <div class="col-md-12">
        <div class="card">
            <div class="card-body">
                <button class="btn btn-primary" type="submit">Сохранить</button>
            </div>
        </div>
    </div>
</div>
<br>
@if($item->exists)
    <div class="row justify-content-center">
        <div class="col-md-12">
            <div class="card">
                <div class="card-body">
                    <ul class="list-unstyled">
                        <li>ID: {{ $item->id }}</li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
    <br>
    <div class="row justify-content-center">
        <div class="col-md-12">
            <div class="card">
                <div class="card-body">
                    <div class="form-group">
                        <label for="created_at">Создано</label>
                        <input type="text" value="{{ $item->created_at }}" class="form-control" id="created_at" disabled>
                    </div>
                    <div class="form-group">
                        <label for="updated_at">Изменено</label>
                        <input type="text" value="{{ $item->updated_at }}" class="form-control" id="updated_at" disabled>
                    </div>
                    <div class="form-group">
                        <label for="deleted_at">Удалено</label>
                        <input type="text" value="{{ $item->deleted_at }}" class="form-control" id="deleted_at" disabled>
                    </div>
                </div>
            </div>
        </div>
    </div>

@endif

Результат

Для теста

Делаем метод update в CategoryController следующего вида:

/**
 * Update the specified resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function update(Request $request, $id)
{
    dd(__METHOD__, $request->all(), $id);
}

И пробуем на странице редактирования категории нажать кнопку "Сохранить". Мы должны попасть на страницу с выполненным методом update.