Maison > Questions et réponses > le corps du texte
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
P粉2587888312023-09-12 16:58:05
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< /code> 可能会在
scopeForUser
est à l'origine du problème.
Peut-être qu'une autre approche pourrait ressembler à ceci :
public function scopeForUser($query, User $user) { if ($user->can('view-all-projects')) { return $query->withBudget() ->with(['customer:id,company_id' => ['company:id,name']]) ->orderBy('end_date', 'desc'); } return $query->withBudget() ->with(['customer:id,company_id' => ['company:id,name']]) ->where('user_id', $user->id) ->orWhere(function ($query) use ($user) { $query->whereHas('users', function ($query) use ($user) { $query->where('users.id', $user->id); }) ->orWhereHas('tasks', function ($query) use ($user) { $query->where('user_id', $user->id); }); }) ->orderBy('end_date', 'desc'); }