Reputation: 403
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
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
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