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

tan's avatar
Level 1

Create a model with a required relationship

Hey.

I'm trying to create a model that has a relationship which is required for the object to be valid. Querying this model should not return any results that are missing this relationship. It seems like global scopes are the best option for this scenario, however I've been unable to make this work. Am I doing something wrong? Perhaps there's a better way?

Here is a simplified version of the model.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Car extends Model
{
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('has_details', function ($builder) {
            $builder->has('details');
        });
    }

    public function details()
    {
        return $this->hasOne(Details::class);
    }
}

And here is a one-to-many relationship method on another model.

public function cars()
{
    return $this->hasMany(Car::class);
}

Without the global scope, this code returns all related "cars", including ones without "details". With the global scope, no "cars" are returned. I want this code to only return "cars" with "details".

Thank you.

0 likes
6 replies
tan's avatar
Level 1

Does anyone know why this code doesn't have the intended effect? Is it not possible to use has() on a scope?

Alamin's avatar

Could you please mention table structure of car & details ?

tan's avatar
Level 1

@Snapey I have no control of the source of the data, so I cannot enforce any rules from that end. Your second suggestion would not work in my situation. I don't want to have default values for the "Details" model. I don't want that "Car" to be returned at all. Thanks.

tan's avatar
Level 1

@Snapey I'm using the Anonymous Global Scopes pattern described here (look for the section with that title). This style works for me in other cases. It's this use case that isn't working for me.

Please or to participate in this conversation.