我需要为当前登录的用户编写一个提取项目的范围。如果当前登录的用户具有view-all-projects
权限,则我希望列出系统中的所有项目,否则我希望列出登录用户创建的项目或登录用户通过任务分配到的项目。我尝试在Project
模型中编写以下范围:
public function scopeForUser($query, User $user)
{
if ($user->can('view-all-projects')) {
return $query->withBudget()
->with(['customer:id,company_id' => ['company:id,name']])
->latest()
->orderBy('end_date', 'desc');
}
return $query->withBudget()
->with(['customer:id,company_id' => ['company:id,name']])
->where(function ($query) use ($user) {
$query->where('user_id', $user->id)
->orWhereHas('users', function ($query) use ($user) {
$query->where('users.id', $user->id);
})
->orWhereHas('tasks', function ($query) use ($user) {
$query->where('user_id', $user->id);
});
})
->latest()
->orderBy('end_date', 'desc');
}
withBudget
的范围如下所示
public function scopeWithBudget($query)
{
return $query->addSelect(['budget' => function ($subQuery) {
$subQuery->selectRaw('sum(cost)')
->from('tasks')
->whereColumn('project_id', 'projects.id');
}]);
}
到目前为止,它确实工作,但并不精确。有时,当我知道登录的用户是管理员并拥有所有权限时,它只获取几个项目,而且项目以降序排列,我认为是created_at
而不是end_date
任何想法,我可以解决这个问题?如果你需要更多的信息,请让我知道
编辑如果我删除一些查询,下面的代码片段可以正常工作:
if ($user->hasPermissionTo('view-all-projects')) {
return $query->latest();
} else {
return $query->where(function ($query) use ($user) {
$query->where('user_id', $user->id)
->orWhereIn('id', function ($query) use ($user) {
$query->select('project_id')
->from('tasks')
->where('user_id', $user->id);
});
});
}
然后我在一个动作中获取项目,如:
<?php
namespace App\Actions;
use App\Models\Project;
// use Illuminate\Support\Collection;
use Illuminate\View\View;
class ListProjects
{
public function __invoke(): View
{
$projects = Project::forUser(auth()->user())->get();
return view('projects.index', ['projects' => $projects, 'projectsCount' => $projects->count()]);
}
}
虽然上面的代码段的作品,但它不做一件事(忘记了急于加载现在),但我需要的项目,根据截止日期前剩余的时间列出。所以它应该列出的项目几乎即将到期,项目有更多的时间已经到期的项目,在该顺序
1条答案
按热度按时间tvmytwxo1#
我认为排序的问题很可能是你调用了
latest()
和orderBy('end_date', 'desc')
,因为latest()
是在created_at
的基础上工作的。你可能根本不需要调用latest()
,因为你正在添加自己的排序。至于用户作用域问题,我想知道您使用两个
orWhereHas
调用而不是whereHas
和orWhereHas
是否会导致scopeForUser
出现问题。也许另一种方法看起来像这样: