Mostafa Abedi
Mostafa Abedi

Reputation: 541

Laravel : Get all models that their last relationship have some condition

I have two models Post and Comment, i'd like to get all posts that their last comment is active:

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

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

i tried this solution :

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

and in my controller :

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

but in this solution if the last comment is not active Previous comment will be taken

Upvotes: 3

Views: 556

Answers (5)

Set Kyar Wa Lar
Set Kyar Wa Lar

Reputation: 4634

According to your question, the Post model has many Comments. And you want to get the comment from the post where active is one and must be the lastest id.

Get the last comment like the following

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

Get all posts which had the lastComment like the following

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

And filter the latestCommentPosts like the following

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

Or, you can archive by one query like the following as well.

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

Like that, you got all the latest comment with active is 1.

Upvotes: 0

Mozammil
Mozammil

Reputation: 8750

I am not sure if there's another simpler way of doing this, but maybe you can try it with a sub-query?

$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();

Upvotes: 2

Iftikhar uddin
Iftikhar uddin

Reputation: 3182

Shouldn't this

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

be

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

Upvotes: 1

Goms
Goms

Reputation: 2644

I think the code below should work !

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

public function lastComment()
{
  return $this->comments()->latest()->first();
}

Upvotes: 1

Josh Young
Josh Young

Reputation: 1366

->latest() only orders the posts by created_at so to get only the latest comment you need ->latest()->first()

Upvotes: 1

Related Questions