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