bfl
bfl

Reputation: 403

Create a model with a required relationship

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.

Upvotes: 0

Views: 226

Answers (2)

mike.bronner
mike.bronner

Reputation: 1239

You might try eager-loading the relationship, so that the has() inspection will actually see something. (I suspect because the relationship is not loaded, the details relationship is never populated.)

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class Car extends Model
{
    protected $with = ['details'];

    protected static function boot()
    {
        parent::boot();

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

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

Upvotes: 0

Arbron
Arbron

Reputation: 161

You have some mistakes at Anonymous Global Scopes declaration:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

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

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

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

Upvotes: 1

Related Questions