Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

FounderStartup's avatar

What will be the query ?

One USER can have multiple LISTINGS and a LISTING can have multiple RESPONSES.

I need to calculate total number of responses of listings by a USER.

What will be the query ?

Models

class Listing extends Model
{

    use HasFactory;
    protected $guarded = [];


    public function messages(){
        return $this->hasMany(Message::class,'listing_id','id');
    }

    public function responses(){
        return $this->hasMany(ListingResponse::class,'listing_id','id');
    }


class ListingResponse extends Model
{
    use HasFactory;
    protected $guarded = [];

    public function user(){
        return $this->belongsTo(User::class,'user_id','id');
    }

    public function listing(){
        return $this->belongsTo(Listing::class,'listing_id','id');
    }
0 likes
5 replies
Nakov's avatar

Something like this:

User::with(['listings' => function ($query) 
	{ 
		$query->withCount('responses'); 
	}])
->get();

now each of your listing will have responses_count property.

1 like
FounderStartup's avatar

@Nakov I have the user id. So how I will calculate total responses of all the USER listings ?

Nakov's avatar

@FounderStartup

$user = User::with(['listings' => function ($query) 
	{ 
		$query->withCount('responses'); 
	}])
->find(USER_ID);

$totalResponses = $user->listings->sum('responses_count');
1 like
PovilasKorop's avatar
Level 11

@nakov added a working query, but I would argue that it is not efficient enough - you're loading listings although you probably don't need them, as you need only responses_count, right?

So I would suggest a hasManyThrough relationship.

User.php:

    public function responses()
    {
        return $this->hasManyThrough(ListingResponse::class, Listing::class);
    }

And then you do:

$user = User::withCount('responses')->find($userId);

And then, in the Blade, you have $user->responses_count as the result.

3 likes

Please or to participate in this conversation.