Laravel: получить все модели, в которых их последние отношения имеют какое-то условие

У меня есть две модели Post и Comment, я хотел бы получить все сообщения, в которых их последний комментарий активен:

// Model Post
public function comments()
{
  return $this->hasMany('comments');
}

//Model Comment
public function post()
{
  return $this->belongsTo('post');
}

я попробовал это решение:

public function lastComment()
{
 return $this->hasOne('comment')->latest()
}

и в моем контроллере:

$postsWithLastActiveComment = Post::whereHas('lastComment', function($q){
  $q->where('active',1);
})->all();

но в этом решении, если последний комментарий не активен, будет взят предыдущий комментарий

См. stackoverflow.com/a/50687657/4848587.

Jonas Staudenmeir 20.01.2019 14:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
3
1
236
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

->latest() упорядочивает сообщения только через created_at, поэтому, чтобы получить только последний комментарий, вам нужен ->latest()->first().

Вызов неопределенного метода Illuminate\Database\Query\Builder::getRelated()

Mostafa Abedi 20.01.2019 08:31

первый метод не разрешен в запросе отношений

Mostafa Abedi 20.01.2019 08:34

Вы получаете ошибку getRelated, потому что ваше отношение комментариев является HasMany, а не HasOne (даже если вам нужен только один). Так что можно поставить: $this->hasMany('comments')->latest()->first()

Matt Wohler 20.01.2019 08:36

Я думаю, что приведенный ниже код должен работать!

public function comments()
{
  return $this->hasMany('comments');
}

public function lastComment()
{
  return $this->comments()->latest()->first();
}
Ответ принят как подходящий

Я не уверен, есть ли другой более простой способ сделать это, но, может быть, вы можете попробовать его с помощью подзапроса?

$lastComment = Comment::select('active')
    ->whereColumn('post_id', 'posts.id')
    ->latest()
    ->limit(1)
    ->getQuery();

$posts = Post::select('posts.*')
    ->selectSub($lastComment, 'last_comment_is_active')
    ->having('last_comment_is_active', 1)
    ->get();

Разве это не должно

$postsWithLastActiveComment = Post::whereHas('lastComment', function($q){
  $q->where('active',1);
})->all();

быть

 $postsWithLastActiveComment = Post::whereHas('lastComment', function($q){
    $q->where('active',1);
 })->get();

Согласно вашему вопросу, у модели Post много комментариев. А вы хотите получить комментарий к сообщению, где активен один и должен быть последним идентификатором.

Получите последний комментарий, как показано ниже.

public function lastComment()
{
    return $this->hasOne('comment')->latest()->take(1);
}

Получите все posts, у которых есть lastComment, как показано ниже.

$latestCommentPosts = Post::whereHas('lastComment')->get()

И отфильтруйте latestCommentPosts, как показано ниже.

$latestCommentPosts->where('active', 1)->get()

Или вы также можете архивировать по одному запросу, как показано ниже.

Post::whereHas('comments', function($q) { 
    $q->where('active', 1); 
})->get()

Таким образом, вы получили все последние комментарии с активным значением 1.

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