Рубрики (Channels)

Рубрики являются родительскими объектами блога, к ним относятся все темы, а к темам, в свою очередь, относятся все сообщения. Поэтому в этом разделе поговорим о рубриках, а в следующих разделах перейдем к темам и сообщениям.

Для рубрик мы указали следующие два маршрута:
Route::get('channels/create', 'ChannelsController@create');
Route::post('channels', 'ChannelsController@store');
Первый маршрут нужен для перехода на страницу с формой создания рубрики, а второй отвечает за сохранение полученных из формы данных в базе данных. В обоих случаях используется ChannelsController.

Создадим файл ChannelsController.php в папке Http/Controllers. Его содержимое будет следующим:
namespace App\Http\Controllers;

use App\Channel;
use Illuminate\Http\Request;

class ChannelsController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function create()
    {
        return view('channels.create');
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|max:50',
            'slug' => 'required|max:50',
        ]);

        $channel = Channel::create([
            'name' => request('name'),
            'slug' => request('slug')
        ]);

        return back();
    }
} 
Как видно из кода контроллера вид для рубрик у нас только один – 'channels.create'. После сохранения новой рубрики в БД будем возвращаться на эту же страницу.

Список рубрик у нас помещен в верхнем навигационном меню (nav.balde.php) в следующем участке кода:
<li role="separator" class="divider"></li>
    @foreach ($channels as $channel)
        <li><a href="/threads/{{ $channel->slug }}">{{ $channel->name }}</a></li>
    @endforeach
</ul>
В цикле используется переменная $channels, она должна быть доступной глобально, поэтому воспользуемся услугами класса AppServiceProvider. В методе boot() нужно добавить следующий код:
public function boot()
{
    ...
    $channels = Channel::all();
    \View::share('channels', $channels);
}
Чтобы переменная была доступна во всех видах, мы использовали метод: View::share('key', 'value').

Мы еще не добавили вид создания рубрики – 'channels.create'. Для этого нам нужно создать папку channels (внутри resources/views) и в ней создать файл create.blade.php. Содержимое файла должно быть следующим:
@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Создать новую Рубрику</div>

                    <div class="panel-body">
                        <form method="POST" action="/channels">
                            {{ csrf_field() }}

                            <div class="form-group">
                                <label for="title">Название:</label>
                                <input type="text" class="form-control" id="name" name="name"
                                       value="{{ old('name') }}" required>
                            </div>

                            <div class="form-group">
                                <label for="title">Алиас (псевдоним):</label>
                                <input type="text" class="form-control" id="slug" name="slug"
                                       value="{{ old('slug') }}" required>
                            </div>

                            <div class="form-group">
                                <button type="submit" class="btn btn-primary">Сохранить</button>
                            </div>

                            @if (count($errors))
                                <ul class="alert alert-danger">
                                    @foreach ($errors->all() as $error)
                                        <li>{{ $error }}</li>
                                    @endforeach
                                </ul>
                            @endif
                        </form>

                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection
Теперь осталось добавить нужный код в модель Channel. Готовый вариант файла Channel.php должен выглядеть следующим образом:
namespace App;
use Illuminate\Database\Eloquent\Model;

class Channel extends Model
{
    protected $guarded = [];
        
    public function getRouteKeyName()
    {
        return 'slug';
    }

    public function threads()
    {
        return $this->hasMany(Thread::class);
    }
}
Немного о коде.
Массив $guarded оставляем пустым, чтобы пользователь мог беспрепятственно создавать новые рубрики.

В методе getRouteKeyName() возвращаем название поля (slug), по которому Laravel будет автоматически возвращать нужную модель (Channel). Например, когда нам нужно будет отобразить список тем определенной рубрики, по URI-сегменту threads/{channel} Laravel выберет нужную рубрику, используя поле slug, указанное в ссылке на странице. Пример ссылки был указан выше, в коде из навигационной панели.

В методе threads() указываем, что рубрика включается в себя разные темы.