I have a table of threads, and on the index page I want to display the latest comment of the thread. So far I have selected the latest comment and try to display it on the page, but it only displays the latest comment overall, not the latest for the specific post
So my ThreadsController looks like this right now, selecting all the comments and displaying the latest one first.
public function index()
{
$threads = Thread::latest()->paginate(10);
$latestComment = Comment::latest()->first();
return view('threads.index', compact('threads', 'latestComment'));
}
Thread model
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
Comment Model
public function user() {
return $this->belongsTo(User::class);
}
public function thread()
{
return $this->belongsTo(Thread::class);
}
public function commentable() {
return $this->morphTo();
}
So how do I select the latest comment from the specific thread and display it on the index?
Edit:
Controller:
public function index()
{
$threads = Thread::latest()->with('comments')->paginate(10);
return view('threads.index', compact('threads'));
}
Index blade:
@foreach($threads as $thread)
{{ $thread->latestComment->user->name }}
@endforeach
Comments table migration
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('body');
$table->unsignedBigInteger('commentable_id');
$table->string('commentable_type');
$table->timestamps();
});
}
You have defined your relationship between a Thread
and Comment
correctly, but you're not making use of that relationship in the index
function of your ThreadsController
. You're just grabbing the latest 10 Threads
and the most recent Comment
, but not the comment related to your Thread
.
What you're wanting is to get all your Threads
and pass them to your view with their latest Comment
.
You can use eager loading
to attach your Comment
relationships to your models.
Thread::latest()->with('comments')->paginate(10);
That will grab your 10 latest Threads
along with their Comments
. So in your view you could do something like:
@foreach ($threads as $thread)
{{ $thread->comments()->latest('id')->first()->comment }}
@endforeach
Whilst this works, it's a bit verbose. So what you can do is piggy back off your comments
function to return just the most recent Comment
as a relationship.
class Thread extends Model
{
use HasFactory;
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
public function latestComment()
{
return $this->morphOne(Comment::class, 'commentable')->latest('id');
}
}
This gives you shorter method for accessing the latest Comment
for a Thread
.
So going back to your scenario;
In your ThreadsController.php
public function index()
{
$threads = Thread::latest()->with('latestComment')->paginate(10);
return view('threads.index', compact('threads'));
}
Then in your index.blade.php
file
@foreach ($threads as $thread)
{{-- Access whatever properties you have on your comment --}}
{{ $thread->latestComment->id }}
@endforeach