Thiago Valente
Thiago Valente

Reputation: 703

Laravel Eloquent Multiple Relationship

I want this object only if it has all the necessary relationships.

At the moment my code:

StudentController

$student = Student::with('inscriptions','inscriptions.classroom')
                    ->find($request->user()->id);

Student

public function inscriptions()
{
    return $this->hasMany('App\InscribedStudent');
}

InscribedStudent - Note: "Registration Open"

public function classroom()
{
    return $this->hasOne('App\Classroom', 'id')->where('registration_open', true);
}

Json Return When haven't registration opened

{
    "inscriptions": [
        {
            "id": 1,
            "student_id": 1,
            "classroom_id": 1,
            "deleted_at": null,
            "created_at": "2019-07-04 23:34:48",
            "updated_at": "2019-07-04 23:34:48",
            "classroom": null
        }
    ]
}

I want to do something like that, because I don't need the object InscribedStudent if I haven't a classroom.

public function inscriptions()
{
    return $this->hasMany('App\InscribedStudent')
                ->hasOne('App\Classroom', 'id')
                ->where('registration_open', true);
}

Upvotes: 0

Views: 2018

Answers (1)

newUserName02
newUserName02

Reputation: 1678

You can use has() or whereHas() to check that the classroom exists.

https://laravel.com/docs/5.8/eloquent-relationships#querying-relationship-existence

// this will only get students that have a classroom through inscriptions
$students = Student::has('incriptions.classroom')
                   ->with('inscriptions.classroom')
                   ->get();

// this will get students, but only fetch inscriptions if there is a classroom
$students = Student::with(['inscriptions' => function($inscriptionQuery) {
                         $inscriptionQuery->has('classroom')->with('classroom');
                     }])
                     ->get();

You can also make a custom scope on the Student model if you want to use that instead.

// this will only get students that have a classroom through inscriptions
public function scopeHasClassroom($query)
{
    $query->has('inscriptions.classroom')
          ->with('inscriptions.classroom');
}

// this will get students, but only fetch inscriptions if there is a classroom
public function scopeHasClassroom($query)
{
    $query->with(['inscriptions' => function($inscriptionQuery) {
        $inscriptionQuery->has('classroom')->with('classroom');
    }]);
}

Then you can call the custom scope like this:

$students = Student::hasClassroom()->get();

https://laravel.com/docs/5.8/eloquent#query-scopes

Upvotes: 1

Related Questions