Bonjour,

J'ai créé 5 tables comme ceci :

users (id)
travels (id | name)
criteria (liste de critère, id | name)
criterion_user (table pivot, user_id | criterion_id)
criterion_travel (table pivot, travel_id | criterion_id)
Ce que je dois faire, c'est ressortir les voyages pour l'user 1.

Donc, le cheminement serait de récupérer les criterion_user de l'user 1, puis de récupérer les criterion_travel qui sont identique à ceux de l'user. Pour au final, sortir les travels.

$user = \App\Model\User::with('criteria')->where('id', 1)->first();

$list_criteria = null;

foreach($user->criteria as $criterion)

{

    $list_criteria[] = $criterion->name;

}

if($list_criteria)

{

    $travels = \App\Model\Travel::whereHas('criteria', function($q) use($user, $list_criteria) {

        $q->whereIn('name', $list_criteria)->whereHas('users', function ($q) use($user) {

            $q->where('user_id', $user->id);

        });

    })->get();
}

Le souci c'est que le whereIn ne prend pas tous les termes, mais un par un....

Je sèche, merci de votre aide

18 réponses


Salut, de quelle manière sont liés tes models ?

Je vais faire une petit schéma, ca sera plus clair peut être.

Sur le schéma, on voit que l'utilisateur 1 a choisi les critères 2 et 11.
Je veux récupérer les voyages (travels) ayant ces mêmes critères.

Donc, ici, je cherche dans criterion_traveloù les criterion_id sont 2 et 11. J'obtiens le travel 4.

Donc, le voyage ressorti devrait être "Voyage : Haïti"

C'est plus clair ?

Merci de ton aide

Hello Vincent,

Tente ceci :

$user = \App\Model\User::with('criteria')->where('id', 1)->first();

$travels = \App\Model\Travel::has('criteria')->whereHas('criteria', function($query) use ($user) {
    $query->whereIn('id', $user->criteria->pluck('id')->toArray());
})->groupBy('id', 'ASC')->get();

J'espère que j'ai bien compris ton souci.

Bonjour,

En fait, c'est bien plus compliqué en fait. Si tu regardes cette exemple :

Mes critères :
Baroudeur (1)
Feru de culture (2)
Amérique du Sud (6)
Asie du Nord Est (8)
Asie du Sud Ouest (10)

Liste des voyages existants :
Voyage : Koweït (1)

  • Baroudeur (1)
  • Asie du Sud Ouest (10)
    Voyage : Réunion (2)
  • Feru de culture (2)
  • Afrique (4)
    Voyage : Grèce (3)
  • Comfy (3)
  • Europe de l'Ouest (12)
    Voyage : Haïti (4)
  • Baroudeur (1)
  • Amérique du Nord (5)
    Voyage : Azerbaïdjan (5)
  • Feru de culture (2)
  • Asie du Sud Ouest (10)
    Voyage : Cameroun (6)
  • Comfy (3)
  • Afrique (4)

Dans ta requête, il me renvoie le voyage à la Réunion, or, dans mes critères, je n'ai pas dit que j'étais intéressé par l'Afrique.

Et c'est là toute la complexité

Qu'est-ce que te retourne cette partie :

dd($user->criteria->pluck('id')->toArray());

array:7 [▼
0 => 1
1 => 2
2 => 3
3 => 4
4 => 6
5 => 8
6 => 10
]

j'ai du enlever le ASC dans le group by car il dit que c'est pas une colonne valide.

Donc ton user est en pivot sur les critères 1 2 3 4 6 8 10.
Il n'est pas impossible que tu aies des valeurs résiduelles d'un autre test.
Quel est l'id du critère de l'Afrique ?

Edit : oui en effet, le ASC n'avait rien à faire là, j'avais en tête un orderBy par la suite, au temps pour moi.

Afrique => 4

Donc quand tu dis : Dans ta requête, il me renvoie le voyage à la Réunion, or, dans mes critères, je n'ai pas dit que j'étais intéressé par l'Afrique.
En réalité, le criètre 4 est bien enregistré sur ton compte, vu que l'id 4 ressort bien du pluck().

Tu vois ce que je veux dire ? Ou c'est moi qui ne saisi toujours pas ton souci ?

Vu que mes critères de recherches sont
Mes critères :
Baroudeur (1)
Feru de culture (2)
Amérique du Sud (6)
Asie du Nord Est (8)
Asie du Sud Ouest (10)

Je n'ai pas envie de voir un voyage en Afrique.

PS : je viens de découvrir ton site, il est sympa ;)

J'ai réussi à faire qq choses mais il existe peut etre un procédé plus simple.
Skype pour que je te montre mon écran et en discuter ?

Merci

De ce que je comprends, si la méthode pluck retourne l'id 4, ça veut dire que la liste de critère que tu viens de me donner est fausse, par rapport à ce que tu as en base de donnée.

A mon avis, si tu requête ta table, tu vas avoir :
Baroudeur (1)
Feru de culture (2)
Afrique (4)
Amérique du Sud (6)
Asie du Nord Est (8)
Asie du Sud Ouest (10)

En lançant :

dd($user->criteria->pluck('name')->toArray());

Tu as quelle liste ? C'est sensé te retourner le nom des critères de l'user, sous forme de tableau.

PS : Merci, ça fait super plaisir !

array:6 [▼
0 => "Baroudeur"
1 => "Feru de culture"
2 => "Afrique"
3 => "Amérique du Sud"
4 => "Asie du Nord Est"
5 => "Asie du Sud Ouest"
]

dd(\App\Model\Travel::find(2)->criteria->pluck('id')->toArray());

Il me ressort :

array:2 [▼
0 => 2
1 => 4
]

l'id critère 4 est dans les critères de l'user, et du voyage 2 (la réunion).

Du fait que ce voyage fait parti du critère 4, l'user ayant aussi ce critère, ça ressort dans les résultats de la requête. Si tu veux le sortir, il faut que tu supprimes la ligne dans criterion_travel qui contient travel_id 2 criterion_id 4.