Besoin d'aide ?

Problème d'héritage

  • Avatar de XavierDlm
    Membre depuis :
    01/12/2017
    Messages :
    6

    Bonjour , c'est mon premier post sur ce forum donc je vous prie de m'excuser d'avance si mon post n'est pas tres bien formuler.
    Mon problème et que j'ai crée une base de donnée avec de l'héritage (mcd ci dessous)
    https://goopics.net/i/b1NQD
    on peut voir que (produits) est l' entité générique qui a une clé primaire et 14 sous-types qui n'ont pas de clé primaire car elle doivent recuperer celle de produit .
    Et que lors de mes creation de migration pour les 14 sous-type, je ne sais pas comment faire pour pour leur faire prendre en clé primaire celle de produit , ni comment recuperer les autre champ de la table produits qui doivent etre commun avec les 14 sous type

    j'ai tester des chose comme cela mais ca ne marche pas :

    Schema::create('entretoises', function (Blueprint $table) {

    $table->engine = 'InnoDB';
    $table->increments('produits_id');
    $table->string('produits_ref',100);
    $table->string('produits_nom',100);
    $table->float('produits_prix');
    $table->string('produits_description');
    $table->string('produits_image');
    $table->integer('produits_stock');
    $table->string('epaisseur',100);
    $table->string('pcd',100);
    });
    <

    Donc si vous arrivez a me comprendre, pourriez vous m'aidez ou me dire quel concept utiliser , doit on utiliser les relations polymorphique pour faire de l’héritage avec éloquent ?

    Merci d'avance pour votre attention.
  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    1673

    Bonjour,

    Tes sous-types sont des entités et doivent donc avoir une clé primaire sinon tu auras du mal à faire fonctionner tout ça avec Eloquent. Il faut ensuite mettre en relation ces sous-types avec les produits. Comme les produits doivent être reliés selon les cas à différents sous-types il faut établir une relation polymorphique.

    produits
    id
    ref
    nom
    ...
    productable_id (pour l'id de l'enregistrement en relation)
    productable_type (pour la classe du modèle en relation)

    treuils
    id
    marque
    type
    ...

    attelages
    id
    marque
    modèle
    ...

    Il faut bien mettre en place les relations telles qu'expliquées dans la documentation : morphTo dans Produit et morphOne (et pas morphMany parce que tu n'as la relation qu'avec un produit) dans les autres modèles.

  • Avatar de F.M.
    Membre depuis :
    10/07/2017
    Messages :
    32

    Hello,

    Juste en complément ceci :

    T'utilises du Merise donc à priori ton SGBD est de type relationnel (MySql, MariaDB, PostGreS etc..). De fait, il ne s'agit que d'une simulation d'héritage (il existe des SGBD orientés Objet).

    Pour mapper ta BDD relationelle vers un modèle objet il existe des couches soft "magiques" appelées ORM, dont le plus connu est Doctrine, que je t'encourage à utiliser si tu as, comme moi, une grande affinité avec la programmation Objet. Ce package là fait le job : https://www.laraveldoctrine.org/

    Eloquent est tout à fait remarquable (et le post de Bestmomo rappelle que c'est aussi un ORM), il accélère le développement de manière spectaculaire, mais pour moi c'est une des faiblesse de Laravel qui peut parfois tendre vers du "quick and dirty".

  • Avatar de XavierDlm
    Membre depuis :
    01/12/2017
    Messages :
    6

    Bonjour merci de m'avoir répondu mais , j'ai encore un petit problème avec cette héritage , j'ai suivi la documentation laravel sur la relation polymorphique , mais je croit avoir un problème soit dans mes migration soit dans mes models je ne sait pas trop .Pour l'instant pour mes test j'ai crée uniquement 2 sous-type (lazers et entretoises).
    Voici mon erreurInvalid argument supplied for foreach()

    Voici ma migration Produits

    Schema::create('produits', function (Blueprint $table) {
    $table->engine = 'InnoDB';
    $table->increments('id');
    $table->string('ref',20);
    $table->string('nom',100);
    $table->string('descritpion',250);
    $table->string('image',250);
    $table->float('prix');
    $table->integer('stock');
    $table->string('produitable_type');
    $table->rememberToken();
    $table->timestamps();
    });

    Schema::table('produits', function(Blueprint $table) {
    $table->integer('produitable_id')->unsigned();
    $table->foreign('produitable_id')->references('id')->on('entretoises','lazers');
    });

    Migration Entretoises

    Schema::create('entretoises', function (Blueprint $table) {
    $table->engine = 'InnoDB';
    $table->increments('id');
    $table->string('epaisseur',100);
    $table->string('pcd',100);
    $table->timestamps();
    });

    Migration Lazers

    Schema::create('lazers', function (Blueprint $table) {
    $table->engine = 'InnoDB';
    $table->increments('id');
    $table->string('gamme',100);
    $table->timestamps();
    });

    Pour mes models j'ai suivi a la lettre la doc Laravel donc dans la table produits

    public function produitable()
    {
    return $this->morphTo();
    }

    et dans les autre en gros :

    public function produits()
    {
    return $this->morphOne('App\Models\Produit', 'produitable');
    }

    Et voici mon controller

    public function monProfil()
    {
    $user = Auth::user();
    $entretoise =Entretoise::find(1);

    return view('pages/profil')->with('user', $user)->with('entretoise', $entretoise);

    }

    Et le Foreach dans ma vue

    @foreach ($entretoise->produits as $produit)<?php var_dump ($produit); ?> @endforeach

    qui doit servir a m'afficher tout les produit dans entretoise qui on le produitable_id = 1

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    1673

    Bonjour,

    Tu es sûr que tu as des enregistrements ?

    Change le code ainsi :

    public function monProfil()
    {
    $user = Auth::user();
    $entretoises = Entretoise::with('produits')->find(1);

    // Pour voir le contenu de $entretoises ajoute :
    // dd($entretoises);

    return view('pages.profil', compact('user', 'entretoises'));
    }
  • Avatar de XavierDlm
    Membre depuis :
    01/12/2017
    Messages :
    6

    oui j'ai des enregistrement, par contre les enregistrements je l'ai ai fait depuis phpmyadmin en inserant dans la table c'est peut etre ca le probleme ?
    j'ai modifier mon code avec ce que vous m'avez fournit et j'ai ceci comme erreur

    Trying to get property of non-object (View: C:\wamp64\www\trans4\resources\views\pages\profil.blade.php)
  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    1673

    Et ça donne quoi le dd($entretoises) ?

  • Avatar de XavierDlm
    Membre depuis :
    01/12/2017
    Messages :
    6

    Ca m'affiche cela ( desoler de l'attente )

    Entretoise {#435 ▼
    #connection: null
    #table: null
    #primaryKey: "id"
    #keyType: "int"
    #perPage: 15
    +incrementing: true
    +timestamps: true
    #attributes: array:5 [▼
    "id" => 1
    "epaisseur" => "120"
    "pcd" => "16"
    "created_at" => null
    "updated_at" => null
    ]
    #original: array:5 [▼
    "id" => 1
    "epaisseur" => "120"
    "pcd" => "16"
    "created_at" => null
    "updated_at" => null
    ]
    #relations: array:1 [▼
    "produits" => null
    ]
    #hidden: []
    #visible: []
    #appends: []
    #fillable: []
    #guarded: array:1 [▼
    0 => "*"
    ]
    #dates: []
    #dateFormat: null
    #casts: []
    #touches: []
    #observables: []
    #with: []
    +exists: true
    +wasRecentlyCreated: false
    }
  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    1673

    Là on voit que la relation est vide, il n'y a donc pas d'enregistrements dans la table produits reliés à la table entretoises.

    Dans productable_type il faut bien entrer le modèle avec son espace de nom : App\Models\Entretoise.

  • Avatar de XavierDlm
    Membre depuis :
    01/12/2017
    Messages :
    6

    Je vien de tester justement parce que je me demandait si c'etait ca le probleme , j'ai donc mis sa dans mon controlleur

    $entretoise =Entretoise::with('produits')->find(1);
    $produit = new produit();
    $produit->ref= 'ra100';
    $produit->nom= 'dadada';
    $produit->descritpion= 'dedede';
    $produit->image= 'ddddd';
    $produit->stock= '50';
    $produit->prix= '100';
    $produit->produitable_type= '\App\Models\Entretoise';
    $produit->produitable_id= '1';
    $produit->save();

    //dd($produit);
    dd($entretoise);

    dans ma base de donnée phpmyadmin je retrouve bien le produit qui est crée mais le dd($entretoise) ne m'affiche toujours pas de relation ( elle eest toujours null)

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    1673

    Là je vois que tu crées le produit après avoir lancé la requête, donc c'est logique que ça retourne pas le produit. Mais au deuxième lancement ça devrait marcher...

  • Avatar de XavierDlm
    Membre depuis :
    01/12/2017
    Messages :
    6

    Oui effectivement sa marche ! Merci beaucoup de votre aide et bonne soirée

Vous ne pouvez pas répondre à ce sujet.