2
votes

Laravel 5.7. I have a model Cat, with a property visible, and a scope to check for visibility:

class Cat extends Model
{
    public function scopeVisible($query)
    {
        return $query->where('visible', true);
    }

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

I have a second model, Flea:

class Flea extends Model
{
    public function cat()
    {
        return $this->belongsTo('App\Cat');
    }
}

I want to add a similar visibility scope to Flea, so that I would be able to do something like $fleas = Flea::visible()->get(), which would only return Fleas which belong to visible Cats. But I'm not sure how I can reference the parent Cat in the scope method on Flea.

Edit: I try to access the cat() relationship in a scopeVisible method on Flea, but I get this error from Laravel:

Property [cat] does not exist on the Eloquent builder instance.

2

2 Answers

9
votes

Use whereHas():

class Flea extends Model
{
    public function cat()
    {
        return $this->belongsTo('App\Cat');
    }

    public function scopeVisible($query)
    {
        return $query->whereHas('cat', function($query) {
            $query->visible();
        });
    }
}

Then just do:

Flea::visible()->get();
0
votes

You can write your own query :

$fleas = Flea::whereHas('cat', function($q) {
    $q->where('visible', true);
})->get();

Or use the Cat model :

$cats = Cat::visible()->get();

foreach($cats as $cat) {
    foreach ($cat->fleas as $flea) {
        // only fleas with visible cats
    }
}

You can use the query as a local scope in the Flea model.