GluePear
GluePear

Reputation: 7715

Refer to relationship in Laravel Eloquent scope

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.

Upvotes: 5

Views: 8533

Answers (2)

Jonas Staudenmeir
Jonas Staudenmeir

Reputation: 25906

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();

Upvotes: 16

Vincent Decaux
Vincent Decaux

Reputation: 10714

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.

Upvotes: -1

Related Questions