Как отрендерить один пост внутри раздела из функции в контроллере

Я разрабатываю личный блог, но я не могу заставить браузер показать мне, что у меня есть в функции, которая еще не показала мне ни одного сообщения, однако мне удается просмотреть список всех сообщений, я могу просмотреть всего 5 (последних), которые появляются на главной домашней странице.

Теперь я перехожу к той части, где вы нажимаете на заголовок, и все об этом посте должно отображаться. Я проверил код той части, где у меня возникли проблемы, и той части, где foreach не отображается в браузере, может быть, я что-то не так делаю в блейд-части?

PostsController.php

    public function show(Post $slug)
    {
        $post = Post::find($slug);
        return view('posts.show', ['posts' => $post]);
    }

Сообщения/show.blade.php

@extends('layouts.app')

@section('showpost')

    <div>
        @foreach ($posts as $post)
            <h1> {{ $post->title }} </h1>
            <p> {{ $post->body }} </p>
        @endforeach
    </div>

@endsection

веб.php

Route::get('/posts/{post}', 'PostsController@show');

Просто чтобы показать вам, как я ссылаюсь на шаблон, который показывает только один пост.

            @foreach ($posts as $post)
            <li>
                <a href="/posts/{{ $post->slug }}">
                    <h1> {{ $post->title }} </h1>
                </a>
                <p> {{ $post->slug }} </p>
            </li>
            @endforeach

person Eduardo    schedule 19.11.2020    source источник
comment
На самом деле нет необходимости в foreach, если вы хотите показать только один пост. @section('showpost'): это правильное название раздела? Обычно это content, ты @yield('showpost') в своем app.blade.php?   -  person brombeer    schedule 19.11.2020
comment
Я честно думал, что если назвать все разделы «контентом», это как-то помешает, но я думаю, что нет, сейчас я предпочитаю так, это проще. Спасибо. я удалил цикл foreach, и он находит неопределенную переменную, попытался изменить эту часть ['posts' => $post]); на ['post' => $post]); и выдает ошибку другого типа. Свойство [название] не существует в этом экземпляре коллекции.   -  person Eduardo    schedule 19.11.2020


Ответы (2)


Post::find используется для получения модели по ее первичному ключу, который в большинстве случаев называется id. Наследник, в вашем случае вы передаете $slug в качестве аргумента, и поскольку предполагается, что он отображает только один элемент с заданным slug, вы должны использовать Post::where('slug', $slug)->first(), это вернет только один элемент, и вам не придется использовать цикл foreach в show.blade.php шаблон.

Другая проблема здесь

public function show(Post $slug) {
    $post = Post::find($slug);
    return view('posts.show', ['posts' => $post]);
}

Вы используете Route Model Binding, который автоматически установит параметр $slug функции show равным записи в таблице posts, которая имеет id, переданный в запросе URL. Нет необходимости выполнять Post::find($slug)

например, если URL-адрес запроса равен http://localhost:8000/posts/1, здесь id равен 1, поэтому параметр $slug будет заполнен записью с id==1, если только вы не настроили ключ вот так

Определите в App\Models\Post::class вызове метода

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

С этим определением элемент post, который будет извлечен при выполнении бидинга модели маршрута, будет основан на значении столбца slug в таблице posts.

Вы можете узнать больше о маршрутной модели Bidding.

person Yves Kipondo    schedule 19.11.2020
comment
Неопределенная переменная - person Eduardo; 19.11.2020

Чтобы полностью реализовать привязку модели маршрута, вам нужно указать ее в 3 местах: routes.php, PostsController.php и переопределить ее в модели, Post.php:

  1. Передайте желаемую цель внутри метода запроса get и поместите ее в подстановочный знак, это рядом с тем, где вы указываете контроллер и какую функцию использовать внутри контроллера.

Отсюда: Route::get('/posts/{post}', 'PostsController@show');

На это: Route::get('/posts/{slug}', 'PostsController@show');

  1. Переопределите цель (от id до чего угодно) с помощью функции getRouteKeyModel, это точно так же, как предоставил @Yves Kipondo
/**
 * Get the route key for the model.
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}

Настройте функцию show внутри PostsController, передав имя модели и цель, чтобы запрос был завершен. Все это внутри параметра функции. И поскольку вы переопределяете использование идентификатора, вам больше не нужно указывать его внутри запроса Eloquent к базе данных.

Итак, вместо этого:

    public function show(Post $slug)
    {
        $post = Post::find($slug);
        return view('posts.show', ['posts' => $post]);
    }

Измените его на это:

    public function show(Post $slug)
    {
        return view('posts.show', ['post' => $slug]);
    }
person Eduardo    schedule 20.11.2020