2
votes

Utiliser withCount () sur une relation qui a distinct ()

J'ai les modèles suivants:

Question : [title, user_id]

Reply : [body, question_id, user_id]

Utilisateur : [nom]

Comme vous pouvez le voir, une question a de nombreuses réponses, et une réponse appartient à un utilisateur.

J'ai ajouté une relation contributeurs au modèle Question qui récupère tous les utilisateurs qui ont ajouté une réponse (en utilisant les réponses comme table de jointure): p >

Question::withCount('contributors')->get()

J'ai dû utiliser distinct () pour supprimer les doublons, car un utilisateur peut publier de nombreuses réponses sur une seule question et cela fonctionne bien.

Maintenant, le problème se produit lorsque je fais:

public function contributors() 
{
    return $this->belongsToMany(User::class, 'replies')->distinct('user_id');
}

Il ignore l'appel à distinct () et me donne le nombre total d'utilisateurs qui ' J'ai ajouté une réponse (y compris les doublons).

Une idée de la manière dont je peux résoudre ce problème?


0 commentaires

4 Réponses :


0
votes

Vous pouvez le faire en ajoutant un rappel à la méthode withCount .

$questions = Question::withCount('contributors', function ($query) {
    $query->distinct('user_id');
})->get()


5 commentaires

Malheureusement, cela n'a pas fait de différence.


Je pense que la méthode de la relation ne devrait contenir que la définition de la relation, sans distinction. C'est peut-être aussi la raison pour laquelle ma suggestion ne fonctionne pas.


Cela ne fonctionne pas même si je supprime l'appel à distinct de la définition de la relation ... cela donne le même résultat.


désolé pour la mauvaise réponse, j'ai vérifié la méthode distincte dans la documentation Laravel et elle n'accepte aucun argument, elle ne devrait donc être que distinct (). Cependant, je me demande, est-ce que votre premier choix fonctionne - juste obtenir tous les contributeurs, sont-ils distincts? La solution pourrait donc être de sélectionner uniquement user_ids dans la méthode de rappel, puis d'appeler distinct sur la requête.


Merci pour votre aide, j'ai dû utiliser une expression brute comme le dit l'autre réponse.



3
votes

Supprimez distinct () de la relation et utilisez withCount () avec une expression brute:

public function contributors() 
{
    return $this->belongsToMany(User::class, 'replies');
}

Question::withCount(['contributors' => function ($query) {
    $query->select(DB::raw('count(distinct(user_id))'));
}])->get();


2 commentaires

Merci, ça marche. Mais je suppose que cela ne peut pas être utilisé avec la propriété $ withCount pour inclure automatiquement le nombre, non?


Pas directement, mais vous pouvez définir la propriété $ withCount dans le constructeur de votre modèle.



0
votes

Vous pouvez également utiliser la variable ici pour la distinction

public function contributors() 
{
    return $this->belongsToMany(User::class, 'replies');
}

Question::withCount(['contributors' => function ($query) use ($var)  {
    $query->select(DB::raw('count(distinct(user_id))'));
}])->get();


0 commentaires

0
votes

Vous devez continuer à utiliser le distinct ('user_id') dans la méthode de relation pour que des opérations comme celles-ci fonctionnent correctement:

$question->contributors()->count();
$question->contributors->count();
$question->contributors()->get()->count();

sinon, dans certains cas, vous obtiendrez des résultats différents. p>


0 commentaires