Ich muss einen Bereich schreiben, um Elemente für den aktuell angemeldeten Benutzer abzurufen. Wenn der aktuell angemeldete Benutzer die Berechtigung „Alle Projekte anzeigen“ hat, möchte ich alle Projekte im System auflisten, andernfalls möchte ich die Projekte auflisten, die vom angemeldeten Benutzer erstellt oder durch Aufgaben im Benutzer zugewiesen wurden. Ich habe versucht, den folgenden Bereich im Project
-Modell zu schreiben:
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'); }Das Sortiment von
withBudget
ist wie folgt
public function scopeWithBudget($query) { return $query->addSelect(['budget' => function ($subQuery) { $subQuery->selectRaw('sum(cost)') ->from('tasks') ->whereColumn('project_id', 'projects.id'); }]); }
Bisher funktioniert es, aber es ist nicht genau. Manchmal, wenn ich weiß, dass der angemeldete Benutzer ein Administrator ist und über alle Berechtigungen verfügt, werden nur wenige Elemente angezeigt und die Elemente werden außerdem in absteigender Reihenfolge sortiert. Ich denke, created_at
statt Enddatum< /代码>
Irgendwelche Ideen, wie man dieses Problem lösen kann? Wenn Sie weitere Informationen benötigen, lassen Sie es mich bitte wissen
Bearbeiten Wenn ich einige Abfragen entferne, funktioniert das folgende Code-Snippet:
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); }); }); }
Dann bekomme ich den Artikel per:
<?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()]); } }
Obwohl das obige Code-Snippet funktioniert, bewirkt es eines nicht (vergessen Sie vorerst das Eager Loading), aber ich muss die Elemente basierend auf der verbleibenden Zeit bis zum Stichtag auflisten. Es sollten also in der Reihenfolge Artikel aufgelistet werden, die bald fällig sind, Artikel, die mehr Zeit haben, Artikel, die bereits fällig sind
我认为排序问题可能是您调用
latest()
以及orderBy('end_date', 'desc')
作为latest()
工作于created_at
。您可能根本不需要latest()
调用,因为您无论如何都要添加自己的排序。至于用户范围问题,我想知道您是否使用两个
orWhereHas
调用而不是whereHas
和orWhereHas 可能会在
scopeForUser
中引起问题。也许另一种方法可能如下所示: