2
votes

I've got a situation where I've got Posts, Users and Comments.

Each comment stores a post_id and a user_id. What I want to do is get all of a user's comments on a particular post, so that I can do a call like this:

$comments = Auth::User()->comments(post_id=x)->text

(where I know what x is)

I have:

User->HasMany(comments)
Comments->HasOne(User)
Comments->HasOne(Project)
Project->HasMany(comments)

I feel like there needs to be a where or a has or a wherehas or something thrown in.. the best I can manage is that I pull Auth::User()->comments into an array and then search through the array until I find the matching post ID.. that seems wasteful.

3

3 Answers

1
votes

with doesn't apply any join, so you can't reference other table.

You can use this:

// User model
public function comments()
{
  return $this->hasMany('Comment');
}

// Comment model
public function scopeForPost($query, $postId)
{
  $query->where('post_id', $postId);
}

// then you can do this:
Auth::user()->comments()->forPost($postId)->get();

Alternatively you can eager load comments with constraint:

User::with(['comments' => function ($q) use ($postId) {
   $q->where('post_id', $postId);
}])->find($someUserId);

// or exactly the same as above, but for already fetched user:
// $user .. or
Auth::user()->load(['comments' => function ($q) use ($postId) {
   $q->where('post_id', $postId);
}]);

// then you can access comments for $postId just like this:
Auth::user()->comments; // collection
0
votes

When you need to filter your relations, you just have to do it in your Eloquent query:

$data = User::with('posts', 'comments')
          ->where('users.id', Auth::User()->id)
          ->where('posts.id', $postID)
          ->get();

Then you can

foreach($data->comments as $comment)
{
   echo $comment->text;
}
0
votes

Your Comments table would have foreign keys Post_Id and User_ID

To Access all the comments of a particular post from a particular user , can you try this way?

Comment::select('comments.*')
                        ->where('comments.user_id', Auth::user()->id)
                        ->leftJoin('posts','posts.id','=','comments.post_id')
                        ->leftJoin('users','users.id','=','comments.user_id')
                        ->get();

Am sure there is better way to achieve it, but this should give you desired results.

Note use aliases if you have conflicting column names

Let me know if this worked.