简体   繁体   中英

How can i use related model scope inside whereHas Laravel 8

I have two models. Task and TaskCheck

in TaskCheck i have

class TaskCheck extends Model
{
    public function task(): BelongsTo
    {
        return $this->belongsTo(Task::class);
    }

    public function owner(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }

    public function scopeOwnedBy(Builder $query, int $userId): Builder
    {
        return $query->where('user_id', '=', $userId);
    }
}

in Task model i have

class Task extends Model
{
    public function taskCheck(): HasMany
    {
        return $this->hasMany(TaskCheck::class)->with(['taskState', 'owner']);
    }
}

And would like to use something like this:

public function scopeHasOwner(Builder $query, int $taskOwnerId): Builder
{
    return $query->whereHas('taskCheck', function ($q) use ($taskOwnerId) {
        $q->hasOwner($taskOwnerId);
    });
}

however this throws exception Call to undefined method App\Models\Task::hasOwner() as it seems inner query is not aware of Task model.

I know I could use this instead and it works

public function scopeHasOwner(Builder $query, int $taskOwnerId): Builder
    {
        return $query->whereHas('taskCheck', function ($q) use ($taskOwnerId) {
            $q->where('user_id', '=', $taskOwnerId);
        });
    }

but i would rather not repeat the where clause in every related model, because there are more related models deeper in relationships which would use similar functionality and i would like to have it on one place only.

In your TaskCheck model, you have ownedBy() scope, but you called hasOwner() in the whereHas query.

Change your query to ownedBy()

$query->whereHas('taskCheck', function ($q) use ($taskOwnerId) {
    $q->ownedBY($taskOwnerId);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM