skip to Main Content

I have three models:

EmailTemplate
EmailSend
Attendee

An EmailSend references both an Attendee and an EmailTemplate:

class EmailSend extends MyBaseModel {
    ...
    public function attendee()
    {
        return $this->belongsTo(AppModalsAttendee::class);
    }
    
    public function template()
    {
        return $this->belongsTo(AppModalsEmailTemplate::class);
    }
    ...
}

and associated belongsTo relationships defined in the other direction.

A hasManyThrough relationship between EmailTemplate and Attendee doesn’t really make sense so I’ve not defined that.

My issue is that I want to make a HasMany relationship between EmailTemplate and EmailSend, where the referenced Attendee’s ‘is_cancelled’ field is 0

I currently have this:

class EmailTemplate extends MyBaseModel {
    ...
    public function sends()
    {
        return $this->hasMany(AppModelsEmailSend::class)
                    ->join('attendees', 'email_sends.attendee_id', '=', 'attendees.id')
                    ->where('attendees.is_cancelled', 0);
    }
    ...
}

which works, but is there a nicer way to do the join, which uses the existing defined relationships, rather than having to reference table names directly?

2

Answers


  1. You can use a whereHas clause to achieve this without using direct joins:

    public function sends()
    {
        return $this->hasMany(AppModelsEmailSend::class)
                    ->whereHas('attendee', function ($query) {
                        $query->where('is_cancelled', 0);
                    });
    }
    
    Login or Signup to reply.
  2. You can use the whereHas method instead of join, but please be aware that whereHas queries are generally slower compared to join queries because whereHas creates a exists query to fetch the results

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search