Laravel 6

Eloquent : ajouter un where d'une sous relation

Avatar de garnierguillaume
garnierguillaume

Bonjour à tous ,

Je débute sur Laravel et dans le cadre du developpement d'une mini boutique en ligne pour m'entrainer , j'aimerais pouvoir afficher les produits qui appartiennent à une catégorie , pour cela j'utilise la méthode donner dans ce post, la relation est identique produit => liaison_produit_categorie=>categorie le code pour le modèle est le suivant :

` namespace App;

use Illuminate\Database\Eloquent\Model;

class Ce_category extends Model {

protected $table = 'ce_category';
public $timestamps = true;
protected $fillable = array('name', 'image', 'description', 'actif');

public function liaison_ce_product()
{
    return $this->hasMany('App\Liaison_ce_product_ce_category');
}

} `

celui du controller :

  public function show($id)
  {
    $product = Ce_product::whereHas('liaison_ce_product_ce_category.ce_category',function($query){
      $query->where('ce_category.id',1);
    });

    dd($product);
  }

Suite à cela , j'ai une erreur BadMethodCallException Call to undefined method App\Ce_product::liaison_ce_product_ce_category()

Je ne vois pas du tout pourquoi j'ai ce message ...

Merci d'avance pour votre aide =)

Posté il y a 7 mois
Avatar de nash
nash

Salut,

Cela depend de ton model et de ton schema de DB. Pour ma part tu auras un model product et un model category. A partir de cela il y a plusieurs facon de faire.

Methode 1 :

Un produit possede une seule catégorie.

Tu auras donc dans ton model product

public function category()
{
    return $this->belongTo(Category::class 'category_id');
}

Mais une category possède plusieurs Product alors dans le model Category:

public function products()
{
    return $this->hasMany(Product::class, 'category_id');
}

Methode 2

Un produit possede plusieurs categories :

Tu auras donc dans ton model product un jointure avec une table alias (en db) avec comme exemple product_category avec un id, product_id et un category_id.

public function categories()
{
    return $this->belongsToMany(Category::class, 'product_category',  'product_id', 'category_id');
}

Dans ton model category tu auras le même style de jointure pour faire par exemple : Une categorie à plusieurs produits

public function products()
{
    return $this->belongsToMany(Product::class, 'product_category', 'category_id', 'product_id');
}

Ce qui nous donnes dans le controller :

$my_id = 1;
Product::whereHas('categories', static function($query)use($my_id) {
    $query->where('category_id', $my_id);
})->get();

ou pour un seul product
->where('id', $ton_product_id)->first() ou ->where('slug', $ton_slug)->first()
Posté il y a 7 mois
Avatar de garnierguillaume
garnierguillaume

Bonjour , voici les différents modèles , ils ont été builder avec laravelsd, comme tu as bien compris , un produit peu avoir plusieurs catégories et une catégorie a plusieurs produits, pour cela je passe par une table de liaison. Ce_product

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Ce_product extends Model 
{

    protected $table = 'ce_product';
    public $timestamps = true;
    protected $fillable = array('name', 'image', 'description', 'quantity', 'actif');

    public function liaison_ce_category()
    {
        return $this->hasMany('App\Liaison_ce_product_ce_category');
    }

    public function liaison_ce_panier()
    {
        return $this->hasMany('App\Liaison_ce_product_ce_panier');
    }

}

Liaison_ce_product_ce_category

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Liaison_ce_product_ce_category extends Model 
{

    protected $table = 'liaison_ce_product_ce_category';
    public $timestamps = false;

    public function liaison_ce_products()
    {
            return $this->belongsToMany(Category::class, 'product_category',  'product_id', 'category_id');

    }

    public function liaison_ce_category()
    {
        return $this->belongsToMany('App\Ce_category');
    }

}

Ce_category

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Ce_category extends Model 
{

    protected $table = 'ce_category';
    public $timestamps = true;
    protected $fillable = array('name', 'image', 'description', 'actif');

    public function liaison_ce_product()
    {
        return $this->hasMany('App\Liaison_ce_product_ce_category');
    }

}
Posté il y a 7 mois
Avatar de nash
nash

Le model Liaison_ce_product_ce_category ne sert rien avec le schema que tu as !

Le model Liaison_ce_product_ce_category peu être utile pour une utilisation particulière pour des données pivot en plus des ForeignKey.

Posté il y a 7 mois
Avatar de garnierguillaume
garnierguillaume

D'accord , donc je peux requêter directement d'une table à l'autre sans passé par celle ci si je comprend bien ?

Posté il y a 7 mois
Avatar de nash
nash

D'accord , donc je peux requêter directement d'une table à l'autre sans passé par celle ci si je comprend bien ?

A condition d'avoir les bonnes jointures -> Regarde bien l'exemple que j'ai donné et adapte le à ton model. J'ai rien inventé, j'ai repris la doc de laravel.

Posté il y a 7 mois
Avatar de garnierguillaume
garnierguillaume

Je te remercie , ca ne fonctionne toujours pas , mais je vais tout reprendre depuis le début :)

Posté il y a 7 mois
Avatar de KYoann
KYoann

Salut, tous ce qui est dit plus haut est à suivre !! A tu un nouveau message d'erreur suite aux dernieres modifications ?

En regardant ton message d'erreur :

Call to undefined method App\Ce_product::liaison_ce_product_ce_category()

Ta classe "Ce_product" ne contient aucune méthode appelé "liaison_ce_product_ce_category()"

Posté il y a 7 mois
Avatar de garnierguillaume
garnierguillaume

Bonjour

Je reviens vers vous car , après avoir parcouru la doc de laravel ( ca fait juste deux semaines que je bosse avec le framework . ) , nash avait indiqué la bonne méthode , je tiens à apporter une précision qui peux échapper , il est possible de definire soit même la foreign key et la local key sur ce principe: return $this->hasOne('App"modele de reference', 'foreign_key', 'local_key'); dans le cadre d'une relation one to one ou return $this->hasMany('App"modele de reference', 'foreign_key', 'local_key'); dans le cadre d'une relation one to many Merci beaucoup en tout cas et a bientot sur le forum !

Posté il y a 7 mois

Vous ne pouvez pas répondre à ce sujet.