2
votes

Comment joindre 3 tables avec les relations éloquentes de Laravel avec Eager Loading?

Ainsi, une commande a une clé étrangère offer_id .

Et une offre a une clé étrangère item_id .

Un article peut faire partie de plusieurs offres. Mais chaque offre a un article.

Une offre peut être en plusieurs commandes. Mais chaque commande a une offre.

Quand je fais ceci:

public function offers()
{
    return $this->belongsToMany(Offer::class);
}

J'obtiens ceci:

public function orders()
{
    return $this->hasMany(Order::class);
}

public function item()
{
    return $this->hasOne(Item::class);
}

Comme vous pouvez le voir, je peux obtenir cela pour cette offre le item_id: 3 Mais je veux obtenir l'article entier; toutes ses colonnes, pas seulement l'identifiant.

Normalement, vous joindriez ces deux tables. Comment faire cela avec Eloquent?

Voici mes relations éloquentes:

Ordre

public function offer()
{
    return $this->belongsTo(Offer::class);
}

Offre

id: 3,
user_id: 1,
offer_id: 5,
created_at: "2019-02-15 00:40:31",
updated_at: "2019-02-15 00:40:31",
offer: {
    id: 5,
    item_id: 3,
    created_at: "2019-02-15 00:39:40",
    updated_at: "2019-02-15 00:39:40"
}

Item final

$orders = Auth::user()->orders()
            ->with('offer')
            ->get();


0 commentaires

3 Réponses :


1
votes

Si vous entendez par nourriture les articles d'une commande, que diriez-vous de:

$orders = Auth::user()->orders()
            ->with('offer', 'offer.orders', 'offer.item')
            ->get();


7 commentaires

Je reçois un RelationNotFoundException Call to undefined relation [items] sur le modèle [App \ Order].


Où est la relation des éléments dans votre projet, est-ce dans le modèle de commande?


Veuillez consulter la description mise à jour. J'ai ajouté les relations.


Ne fonctionne toujours pas: SQLSTATE [42S22]: Colonne introuvable: 1054 Colonne inconnue 'items.offer_id' dans 'clause where' (SQL: select * from items` où items.offer_id in (2, 4, 5)) `De quoi Je vois, il essaie de rechercher un offer_id dans les éléments, qui n'existe pas. Il devrait être l'inverse. Alors peut-être que les relations sont fausses?


Vous avez spécifié une relation dans votre modèle d'offre avec la colonne "item_id". À quoi ressemble la structure du tableau?


Oui. Ainsi, la table orders a un offer_id clé étrangère. Et la table offres a une clé étrangère item_id . C'est tout. Un article peut faire partie de plusieurs offres. Mais chaque offre a un article. Une offre peut être en plusieurs commandes. Mais chaque commande a une offre.


Résolu. La relation entre item et offer a dû être inversée. Merci de m'avoir indiqué la bonne manière.



1
votes

Laravel Eager Loading

En dessous, vous trouverez chargement impatient imbriqué:

Pour charger rapidement des relations imbriquées, vous pouvez utiliser la syntaxe "point". Par exemple, nous allons charger tous les auteurs du livre et tous les contacts personnels de l'auteur dans une déclaration éloquente:

$ books = App \ Book :: with ('author.contacts') -> get ();

Dans votre cas, nous pouvons en obtenir des imbriqués en utilisant la notation par points entre les relations.

$orders = Auth::user()->orders()
            ->with(['offer', 'offer.item'])
            ->get();


6 commentaires

Vous voulez dire offer.items pas offer.orders , n'est-ce pas? Il ne fonctionne toujours pas - RelationNotFoundException Appel à une relation non définie [items] sur le modèle [App \ Offer].


Vous avez dit que l'offre a des commandes, la commande a des articles. Ce serait donc offer.orders.items pour obtenir les articles. Sur votre modèle de commande, vous devez définir votre relation avec le modèle Item. Ce qui serait un $ this-> hasMany () semble-t-il. Si les commandes peuvent avoir de nombreux articles.


Non. Une commande a une offre et une offre a un article. Jetez un œil aux clés étrangères que j'ai données dans les deux premières lignes de ma description pendant que je la mets à jour pour inclure les relations que j'ai dans mon code.


Mon mauvais je l'ai mal lu, donc ce serait order.offers.items . J'ai mis à jour ma réponse ci-dessus, cela devrait fonctionner correctement. Tant que votre modèle d'offre a une relation avec les articles.


@padawanTony Ce ne serait pas des objets, ce ne serait que des objets puisque votre relation est HasOne. Alors s'il vous plaît regardez ma réponse mise à jour.


Ne fonctionne toujours pas: SQLSTATE [42S22]: Colonne introuvable: 1054 Colonne inconnue 'items.offer_id' dans 'clause where' (SQL: select * from items` où items . offer_id in (2, 4, 5)) `D'après ce que je vois, il essaie de rechercher un offer_id dans items , ce qui fait n'existe pas. Il devrait être l'inverse. Alors peut-être que les relations sont fausses?



0
votes

Les réponses de @MihirBhende et @swonder pointent de la bonne manière.

Cela devrait en effet être:

public function offers()
{
    return $this->hasMany(Offer::class);
}

ou (même chose): p >

public function item()
{
    return $this->belongsTo(Item::class);
}

Mais la relation entre les modèles Offer et Item doit être inversée:

Offre

$orders = Auth::user()->orders()
            ->with(['venue', 'offer.food'])
            ->get();

$orders = Auth::user()->orders()
            ->with('venue')
            ->with('offer.item')
            ->get();


0 commentaires