Laravel - замкнутая связь - лучшие практики

Просто пример: скажем, у меня есть модель публикации и модель комментария. У поста, конечно же, есть комментарии, отношения «один ко многим».

Я должен отображать список сообщений с комментариями под ним.

Получу свои сообщения в контроллере: $posts = Post::get(), в вид лезвия передам а потом прошиваю

@foreach($posts as $post)
    {{ $post->title }}
    {{ $post->comments }}
@endforeach

где $post->comments - некоторое соотношение

public function comments()
{
    return $this->hasMany(Comment::class);
}

Как мы знаем, этот запрос будет выполняться много раз.

Теперь мой вопрос: как нам его оптимизировать?

  1. Вернуть Cache::remember в геттер?
  2. Получить (как-нибудь?) Эти комментарии при получении сообщений одним запросом? Что-то вроде запроса на соединение? Я знаю, что могу написать такой запрос, но я говорю о построителе запросов Eloquent. А как тогда получить комментарии внутри цикла? Разве {{ $post->comments }} не вызовет связь снова вместо того, чтобы получать сохраненные данные?
  3. Другое решение?
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
250
3

Ответы 3

Вы можете использовать $posts = Post::with('comments')->get(), чтобы загружать комментарии к сообщению. Подробнее об этом читайте в документации: https://laravel.com/docs/5.7/eloquent-relationships#eager-loading

Кроме того, чтобы отобразить комментарии, вам нужно добавить еще один цикл foreach. Это выглядело бы примерно так:

@foreach($posts as $post)
    {{ $post->title }}
    @foreach($post->comments as $comment)
       {{ $comment->title }}
    @endforeach
@endforeach

Выглядит нормально, но что, если мне нужны какие-то конкретные данные с with? Например, мне нужны не все комментарии, а только их количество?

alanmcknee 27.11.2018 11:10

Тогда вы можете использовать withCount(). Вот документация: laravel.com/docs/5.7/…

Sander 27.11.2018 11:53

да, ты можешь сделать это в контроллере

$minutes = 60;
$posts = Cache::remember('posts', $minutes, function () {
    return  Post::with('comments')->get()
});

в лезвии ты можешь получить вот так

@foreach($posts as $post)
    {{ $post->title }}
    @foreach($post->comments as $comment)
       {{ $comment->title }}
    @endforeach
@endforeach

для получения дополнительной информации прочтите этот статья

Вы, вероятно, уже кэшировали некоторые данные модели в контроллере раньше, но я собираюсь показать вам метод кэширования моделей Laravel, который более детализирован с использованием моделей Active Record.

Обратите внимание, что мы также можем использовать метод Cache :: RememberForever () и полагаться на сборку мусора нашего механизма кэширования для удаления устаревших ключей. Я установил таймер, чтобы кеш был загружен большую часть времени, а новый кеш обновлялся каждые пятнадцать минут.

Метод cacheKey () должен сделать модель уникальной и аннулировать кеш при обновлении модели. Вот моя реализация cacheKey:

public function cacheKey()
    {
        return sprintf(
            "%s/%s-%s",
            $this->getTable(),
            $this->getKey(),
            $this->updated_at->timestamp
        );
    }

    public function comments()
    {
        return $this->hasMany(Comment::class);
    }

    public function getCachedCommentsCountAttribute()
    {
        return Cache::remember($this->cacheKey() . ':comments_count', 15, function () {
            return $this->comments->count();
        });
    }

Будет ли обновление комментариев (добавление / удаление одного) обновлять столбец «updated_at» в сообщениях?

alanmcknee 27.11.2018 11:17

это будет, когда вы защитите $ touches = ['post']; поставить модель комментариев

Ismoil Shifoev 27.11.2018 11:24

Свойство $ touches - это массив, содержащий ассоциацию, которая будет «затронута» при создании, сохранении или удалении комментария.

Ismoil Shifoev 27.11.2018 11:24

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

alanmcknee 27.11.2018 12:16

Другие вопросы по теме