I'm working with Laravel 5 and I've the following Models
PostComment.php
class PostComment extends Model
{
protected $fillable = [
'post_group_id', 'user_id', 'comment_content'
];
public function post(){
return $this->belongsTo('App\PostGroup');
}
public function user(){
return $this->belongsTo('App\User');
}
}
PostGroup.php
class PostGroup extends Model
{
protected $fillable = [
'group_id', 'user_id', 'post_content'
];
public function user(){
return $this->belongsTo('App\User');
}
public function group(){
return $this->belongsTo('App\Group');
}
public function commented(){
return $this->hasMany(
'App\PostComment'
);
}
}
Group.php
class Group extends Model
{
protected $fillable = ([
'id'
]);
public function users(){
return $this->belongsToMany(
'App\User',
'user_group'
);
}
public function members(){
return $this->belongsToMany(
'App\User',
'user_group'
)->wherePivot('state','accepted');
}
public function posted(){
return $this->hasMany(
'App\PostGroup'
);
}
}
My web application presents groups
, in which you can create posts
and in which post you can write comments
. In my database I've the following relationships:
What I want to do is to create a collection of User objects, and then make a query to get all users, subscribed to a group, who have commented on a certain post, in MySQL looks like:
select users.* from users, post_comments where users.id = post_comments.user_id and post_comments.post_group_id="1"
So in my controller I've the following code
$theGroup = Group::find($groupId);
$thePost = PostGroup::find($postId);
$memberList = User::where('id', '<>', Auth::user()->id)->whereIn('id', $theGroup->users->pluck('id'))->
So, what I want to do is to extend that query to get the desidered result with ->get()->sortBy('last_name');
, how can I exted it after the whereIn
?
EDIT
User.php
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token','created_at','updated_at'
];
public function groups(){
return $this->belongsToMany('App\Group','user_group');
}
public function groupsAsAdmin(){
return $this->belongsToMany('App\Group','user_group')->wherePivot('role','admin');
}
public function groupsAsMember(){
return $this->belongsToMany('App\Group','user_group')->wherePivot('state','accepted');
}
public function groupsAsInvited(){
return $this->belongsToMany('App\Group','user_group')->wherePivot('state','pending');
}
public function posted(){
return $this->hasMany('App\PostGroup');
}
public function commented(){
return $this->hasMany('App\PostComment');
}
}
From your description, you already come up with a list of Users
in advance, so that you only will find Posts
with a Comment
of these specific users.
Basically, what you want is to use whereHas($relation, $calback)
to perform the checks you described:
$userIds = [2, 3, 5, 7, 11, 13, 17]; // or query them...
$postId = 123; // the id of the post where we want to look through the comments
User::where('id', '<>', Auth::id())
->whereIn('id', $userIds)
->whereHas('comments', function ($query) use ($postId) {
$query->where('post_group_id', $postId);
})
->get();
This will simply check if a user has written a Comment
for the given post. Because you forgot to post your User
model, I assumed that there is a relation available for the comments
of the user.
You could also combine the first two conditions (user in list, but not the authenticated one) into one, if you want. $userIds = array_diff($userId, [Auth::id()])
does the job. where('id', '<>', Auth::id())
can be dropped from the query then.
If you do also need to check for an active subscription of the user to a group, it will be slightly more complex. But as you commented, you are already finding only users for a group, so this should be fine.
In PostComment, try this
$this->selectRaw(‘user_id, comment_content’)->where(‘post_group_id’, 1)->groupBy(‘user_id’)->get();