Laravel 6

Relation

Avatar de Clement04
Clement04

Bonjour j'essaye de faire un menu d'arborescence pour afficher un style: "Catégorie" > "Sous-catégorie" > "Nom du Produit"

la table categories:

  • id
  • name
  • slug
  • description

la table categories_sub:

  • id
  • parent_id (correspond au champ ID de la table categories)
  • name

table products:

  • id
  • title
  • category_id (pour l'instant correspond à l'id de la table categories)

Pour l'instant j'arrive uniquement à afficher : "Catégorie" > "Nom du produit" avec ce code: Controller:

    public function show($slug)
    {
        $product = Product::with('categories')->where('slug', '=', $slug)->firstOrFail();
        return view('products.show')->with('product', $product);
    }

Model Products:

    public function categories()
    {
        return $this->belongsTo('App\Category','category_id','id');
    }

Blade:

    <ul class="list-group list-g mb-4 list-group-horizontal-md">
        <li class="list-group-item" style="border:none;"><a class="link-list" href="{{route('index')}}">Accueil <i class="pl-1 fas fa-chevron-right"></i></a></li>  
        <li class="list-group-item" style="border:none;"><a class="link-list" href="#"> {{ $product->categories->name }} <i class="pl-1 fas fa-chevron-right"></i></a></li>
        <li class="list-group-item" style="border:none;"><a class="link-list" href="#">enfant de categorie <i class="pl-1 fas fa-chevron-right"></i></a></li>
        <li class="list-group-item" style="border:none;"><strong>{{ $product->title }}</strong></li>
    </ul>

donc je cherche à remplacer "enfant de catégorie" par la sous catégorie. Si vous pouvez m'orienter, j'ai du mal avec les relations d'eloquent encore...

(j'ai créer un model CategorySub pour les sous catégories pour l'instant)

Posté il y a 1 mois
Avatar de nash
nash

Salut,

En faisant simplement la table categories:

  • id
  • parent_id ForeignKey Null
  • name
  • slug
  • description

Model Products:

public function categories()
    {
        return $this->belongsTo('App\Category','category_id','id');
    }

Model category

    public function parent()
    {
        return $this->hasOne(self::class, 'id', 'parent_id');
    }
    
    public function childrens()
    {
        return $this->hasMany(self::class, 'parent_id', 'id'); 
    }

Tu as ici les premices d'un intervallaire

ce qui peux te donner :

public function show($slug)
    {
        $product = Product::with('categories.parent')->where('slug', '=', $slug)->firstOrFail();
        return view('products.show')->with('product', $product);
    }
Posté il y a 1 mois
Avatar de michelange2008
michelange2008

Petite remarque:

Il me semble que l'on se simplifie la tache en nommant systématiquement les id par le nom de leur model: pourquoi appeler la colonne category_id et non pas categorie_id si cela correspond la table categories du modèle Categorie.

Je ne sais que ça change pas le fond de ta question mais cela simplifie grandement les choses.

Posté il y a 1 mois
Avatar de Clement04
Clement04

@nash Du coup pour afficher avec blade il faut faire comment? car là j'ai uniquement ma catégorie et pas ma sous catégorie

Posté il y a 1 mois
Avatar de nash
nash

dans un premier temps toujours un ptit dump dans ta methode de controller Ce qui te permet de suivre ton retour de données

dump($product->toArray())

Ensuite dans ta vue un simple (Attention ici tu as le produit de la category et sa category parent (ci parent present))

{{ $product->categories->parent->name }}

Si tu as besoins des enfants (ci tu as un enfant biensur) tu feras un :

{{ $product->categories->childrens[0]->name }} // ou autre

Mais avant:

public function show($slug)
    {
        $product = Product::with('categories.parent','categories.childrens')->where('slug', '=', $slug)->firstOrFail();
        return view('products.show')->with('product', $product);
    }
Posté il y a 1 mois
Avatar de Clement04
Clement04

@nash je te remercie de ton aide J'ai essayer ce que tu m'as dis dans ton dernier message, j'ai cette erreur: Undefined offset: 0

J'ai donc essayé: {{ $product->categories->name }} et ça marche.

Est-ce bon?

Posté il y a 1 mois
Avatar de nash
nash

Que sort ton dump ?

Posté il y a 1 mois
Avatar de Clement04
Clement04

@nash

array:13 [▼
  "id" => 4
  "title" => "PC Gamer - SSD 2 TO - Windows 10"
  "slug" => "et-dolorum-nostrum-est-aliquam-atque"
  "description" => "Facilis sint ipsum alias velit dolorem. Quae tempore quia atque animi aut. Expedita nostrum alias dolores ipsam amet fugiat itaque. Tempore perspiciatis molesti ▶"
  "price" => 20000
  "image" => "https://d1eh9yux7w8iql.cloudfront.net/product_images/product_images/1551102386.39-thumb.jpg"
  "progress" => "2020-04-17 09:42:07"
  "shipping" => 500
  "category_id" => 2
  "priceoriginal" => 34000
  "created_at" => "2020-04-10T09:42:07.000000Z"
  "updated_at" => "2020-04-10T09:42:07.000000Z"
  "categories" => array:10 [▼
    "id" => 2
    "name" => "Livres"
    "slug" => "livres"
    "description" => "Ton dernier roman est peut-être ici?"
    "image" => "https://www.erbree.fr/wp-content/uploads/2017/11/Bo%C3%AEte-%C3%A0-livre-Image-1024x514.png"
    "created_at" => null
    "updated_at" => null
    "parent_id" => 1
    "parent" => array:8 [▼
      "id" => 1
      "name" => "High Tech"
      "slug" => "high-tech"
      "description" => "Tous ce qui est du domaine de l'informatique"
      "image" => "https://s3-eu-west-1.amazonaws.com/backmarket-home/macbook-air-13-pouces-avec-ecran-retina-2018.jpg"
      "created_at" => null
      "updated_at" => null
      "parent_id" => 0
    ]
    "childrens" => []
  ]
]

(oui c'est dans high teck -> livre, j'ai juste mis dans la sous catégorie livre pour tester :) )

Posté il y a 1 mois
Avatar de nash
nash

donc tu as bien un produit en sous categorie de categorie et cette meme sous categorie n'a pas d'enfants : "childrens" => []

Ou tu change ton produit de category ou tu crée une sous sous category, ce qui ne respecte plus ton schema de depart.

Posté il y a 1 mois
Avatar de Clement04
Clement04

@nash voilà ma bdd

Posté il y a 1 mois

Vous ne pouvez pas répondre à ce sujet.