Je dois écrire une portée pour obtenir des éléments pour l'utilisateur actuellement connecté. Si l'utilisateur actuellement connecté dispose de l'autorisation d'afficher tous les projets, je souhaite répertorier tous les projets du système, sinon je souhaite répertorier les projets créés par l'utilisateur connecté ou attribués par des tâches dans l'utilisateur. J'ai essayé d'écrire la plage suivante dans le modèle 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'); }La gamme de
withBudget
est la suivante
public function scopeWithBudget($query) { return $query->addSelect(['budget' => function ($subQuery) { $subQuery->selectRaw('sum(cost)') ->from('tasks') ->whereColumn('project_id', 'projects.id'); }]); }
Jusqu'à présent, cela fonctionne, mais ce n'est pas précis. Parfois, quand je sais que l'utilisateur connecté est un administrateur et dispose de toutes les autorisations, il n'obtient que quelques éléments et les éléments sont également triés par ordre décroissant, je pense created_at
au lieu de end_date< /代码>
Des idées pour résoudre ce problème ? Si vous avez besoin de plus d'informations, n'hésitez pas à me le faire savoir
Modifier Si je supprime certaines requêtes, l'extrait de code suivant fonctionne :
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); }); }); }
Ensuite, je reçois l'article via :
<?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()]); } }
Bien que l'extrait de code ci-dessus fonctionne, il ne fait rien (oubliez le chargement rapide pour l'instant), mais je dois lister les éléments en fonction du temps restant avant la date limite. Il devrait donc lister dans l'ordre les articles qui doivent bientôt être rendus, les articles qui ont plus de temps, les articles qui sont déjà attendus
Je pense que le problème de commande pourrait être que vous appelez l'appel
latest()
以及orderBy('end_date', 'desc')
作为latest()
工作于created_at
。您可能根本不需要latest()
puisque vous ajoutez de toute façon votre propre commande.En ce qui concerne le problème de portée utilisateur, je me demande si votre utilisation de deux
orWhereHas
调用而不是whereHas
和orWhereHas 可能会在
scopeForUser
est à l'origine du problème.Peut-être qu'une autre approche pourrait ressembler à ceci :