susanBuck / e15-spring22

0 stars 0 forks source link

How can I get the name of the user for each comment to display? #69

Closed pllealfunes closed 2 years ago

pllealfunes commented 2 years ago

Hey guys,

For the comments section of my blog I would like to display the name of the person who wrote a comment next to their comment but I'm running into the issue where I can't display the right name to each comment.

For example Post 1 has 3 comments. The first comment is from Jill and the other two are from Jamal but all of my comments are showing as if Jamal wrote them. In myphpadmin I can see that the first comment belongs to Jill. How can I fix it so that each comment shows the correct name of the user who wrote it?

show.blade

<div id='comments'>
            @if (count($comments) > 0)
                <ul>
                    @foreach ($comments as $comment)
                        <li>{{ $comment->comment }} - by {{ $commentAuthor->name }}</li>
                        @if (Auth::user() && $comment->user_id == Auth::user()->id)
                            <form action='/comments/{{ $comment->id }}/delete' method="POST">
                                {{ csrf_field() }}
                                {{ method_field('DELETE') }}

                                <button type='submit' class='btn btn-danger btn-small'
                                    test='confirm-delete-button'>Delete</button>
                            </form>
                        @endif
                    @endforeach
                </ul>
        </div>
    @endif
    @endif

PostController

/**
     * GET /posts/{id}
     * Show the details for an individual post with their comments
     */
    public function show($id)
    {
        $post = Post::find($id);
        $postAuthor = User::where('id','=',$post->user_id)->first();

        $comments = Comment::where('post_id', '=', $id)->get();

        $commentAuthor = '';
        foreach ($comments as $comment) {
            $commentAuthor = User::where('id','=', $comment->user_id)->first();
        }

        if (!$post) {
            return redirect('/posts/show')->with(['flash-alert' => 'Post not found.']);
        }

        return view('/posts/show', [
            'post' => $post,
            'postAuthor' => $postAuthor,
            'comments' => $comments,
            'commentAuthor' => $commentAuthor,
        ]);
    }
Screen Shot 2022-05-06 at 7 02 45 PM Screen Shot 2022-05-06 at 7 03 24 PM
gkorodi commented 2 years ago

Your "$commentAuthor" is a single variable, that you keep overwriting in your controller, in this line $commentAuthor = User::where('id','=', $comment->user_id)->first(); "Jamal" being the last user in the comments table, that is what the single variable will hold before being passed to the view.

Not sure about your model, but the quickest fix is to have a display only data structure that you pass to your view. Like

$commentRows = [];
foreach(Comment::where('post_id', '=', $id)->get() AS $comment) {
  $usr = User::where('id','=', $comment->user_id)->first();
  $commentRows[] = [ "commentText" => $comment['comment'], "commentAuthor" => $usr['name'] ];
]

...

  return view(....., [  ... 'comments' => $commentRows, .....]);

and pass $rows to the view with all information filled in.

If you have a foreign key from your comments table to the users table (which it looks like you do), you could try $comment->user['name'], instead of querying the users table for every comment in my above example.

pllealfunes commented 2 years ago

@gkorodi Thanks for the reply.

I ran to a similar issue when it came to displaying the author of every blog post but managed another way. I saw online something similar to the $comment->user['name'] you mentioned except I think the format was more like $comment->user->name. I tried both and I'm not sure why either don't work. I would like to try it because as you said it does mean less querying the users table. Below is my Comment Model. Since my public functions is calledusers I did try $comment->users['name'] and $comment->users->name.

Comment Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    use HasFactory;

     public function users()
    {

        return $this->belongsTo(User::class, 'comments');
    }
}
gkorodi commented 2 years ago

Recommend removing the 'comments' part. Check out https://laravel.com/docs/9.x/eloquent-relationships#one-to-one-defining-the-inverse-of-the-relationship to see that the user_id on the comments table could already serve a a foreign key. Depending on how you created the table (via migration or not).

If the foreign key is indeed established from the comments table, via the belongsTo function, then you could follow example.

Also, call the function user instead of users. It is part of the convention for eloquent.

pllealfunes commented 2 years ago

@gkorodi Thank you it worked! I also changed my Post Model to be the same as the Comment Model and now I am able to use $comment->user->name and $post->user->name` in my views.

Table relationships are still a little confusing to me 😅 but thanks for the help!

luannebe commented 2 years ago

@gkoroki Thanks! This helped me too.