3 votes

Comment créer une relation ManyToMany correcte entre un utilisateur et un produit dans Laravel ?

Je travaille sur un projet de boutique en ligne avec Laravel 5.8 et dans ce projet, j'ai voulu ajouter des éléments suivants "Ajouter aux favoris" la possibilité pour les utilisateurs d'ajouter un produit à leur liste de favoris.

J'ai donc créé un modèle comme celui-ci :

class FavouriteProduct extends Model
{
    protected $table = 'favourite_products';
    protected $fillable = ['usr_id','prd_id'];

    public function users()
    {
       return $this->belongsToMany(User::class, 'favourite_products', 'id', 'usr_id');
    }

    public function products()
    {
       return $this->belongsToMany(Product::class, 'favourite_products', 'id', 'prd_id');
    }
}

Et au niveau du modèle de produit, j'ai ajouté ceci :

public function favourites()
    {
        return $this->belongsToMany(Product::class, 'favourite_products', 'prd_id', 'id');
    }

Et voici le modèle de l'utilisateur :

public function favourites()
    {
        return $this->belongsToMany(FavouriteProduct::class, 'favourite_products', 'usr_id', 'id');
    }

Je voulais maintenant m'assurer que j'avais correctement établi la relation. Donc si vous savez que c'est correct ou non, dites-le moi, j'apprécierais vraiment...

2voto

Nicklas Kevin Frank Points 3133

Tout d'abord, une option serait de supprimer votre FavouriteProduct MAIS conservez le modèle favourite_products la table. (Ce qui serait ma suggestion).

Ou bien, vous pouvez également modifier le FavourteProduct de prolonger Pivot au lieu de Model et ajouter ->using(FavouriteProduct::class) aux deux relations favorites sur User y Product .

J'ai détaillé les deux approches ci-dessous.


Option 1 : Une relation simple

Si vous optez pour ma première suggestion, vous devrez apporter les modifications suivantes.

Sur votre Product vous devez ajouter la relation suivante :

public function favouritees()
    {
        return $this->belongsToMany(User::class, 'favourite_products', 'prd_id', 'usr_id')
            ->withTimestamps();
    }

Sur votre User vous devez ajouter la relation suivante :

public function favourites()
    {
        return $this->belongsToMany(Product::class, 'favourite_products', 'usr_id', 'prd_id')
            ->withTimestamps();
    }

Vous pourrez alors ajouter des favoris en procédant comme suit :

$user = User::find($userId);
$product = Product::find($productId);

$user->favourites()->save($product);

Option 2 : un modèle Pivot plus complexe

Il serait préférable que vous n'utilisiez l'option de pivot que si vous avez l'intention d'ajouter des informations et des relations supplémentaires à la base de données. Pivot relation entre les deux modèles.

Comme ceci sur le Product modèle

public function favouritees()
        {
            return $this->belongsToMany(User::class, 'favourite_products', 'prd_id', 'usr_id')->using(FavouriteProduct::class);
        }

Comme ceci sur le User modèle

public function favourites()
    {
        return $this->belongsToMany(Product::class, 'favourite_products', 'usr_id', 'prd_id')->using(FavouriteProduct::class);
    }

Mais je vous suggère de commencer à utiliser une approche plus standard de Laravel ; cela présente de grands avantages, notamment celui de pouvoir suivre les exemples de la documentation lorsqu'on est encore en train d'apprendre.

En utilisant des colonnes telles que usr_id y prd_id ne fait aucune différence, à part rendre votre vie plus difficile. Si vous aviez utilisé user_id y product_id vous n'aurez pas besoin de les passer à chaque relation pour indiquer à Laravel que vous avez décidé d'utiliser votre convention plutôt que celle de Laravel.

Laravel assumera automatiquement les relations, donc si vous ajoutez un fichier belongsToMany il examinera la classe sur laquelle il est implémenté, dans ce cas, User::class et il utilisera automatiquement la clé user_id . Il examinera également la classe dans la relation, par exemple Product::class et utiliser le product_id . À moins, bien sûr, que vous ne lui demandiez d'utiliser quelque chose de spécifique comme vous l'avez fait.

En fin de compte, vous êtes libre de le faire, et il arrive que vous héritiez d'une base de données d'un autre endroit et que vous soyez obligé de le faire.

1voto

Gert B. Points 1135

Par exemple, dans votre modèle d'utilisateur : Vous établissez une relation avec Product : donc changez la classe :

public function favourites()
    {
        return $this->belongsToMany(Product::class, 'favourite_products', 'usr_id', 'product_id');
    }

Je ne suis pas sûr de l'ordre des clés.

0voto

Vous ne pouvez pas avoir deux méthodes de ce même nom dans deux modèles ! Dans le modèle utilisateur, on peut avoir favourites() mais favourites() dans le modèle de produit permet de penser que le produit peut avoir un utilisateur favori. Vous devriez avoir des noms descriptifs pour faciliter la compréhension de votre code. J'ai appris beaucoup à beaucoup à partir de ce tutoriel je vous le recommande.

0voto

sharmeen Points 1

La façon la plus simple de procéder est de vérifier si le produit est présent dans la liste des favoris de l'utilisateur.

$data = Favourite::where(['user_id' => Auth::User()->id, 'product_ref_id' => $productId[1]])->get();

    if (sizeof($data) > 0) {
        Session()->put('snackmsg', 'Product already Exists in Wishlist');
    }else{      
        $Favourite = Favourite::create([
                                            'user_id' => Auth::User()->id,
                                            'product_ref_id' => $productId[1],
                                    ]);
        $totalFavourite = Favourite::where('user_id',Auth::User()->id)->count();
        Session()->forget('totalFavourite');
        Session()->put('totalFavourite', $totalFavourite);
        Session()->put('snackmsg', 'Added to Wishlist');
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X