Laravel 5

Relationréflexive avec Laravel ?

  • Avatar de Pakito
    Membre depuis :
    07/02/2019
    Messages :
    8

    Bonsoir à tous et à toutes,

    Je cherche à créer une relation "reflexive" avec Laravel mais je ne vois pas trop comment m'y prendre.

    J'ai une table "taches" composées de différentes tâches (ID, libelle, dateExecution [...], #etat_id).
    Chaque tâche a un état (table etats : ID, libelle).

    Je souhaiterai faire en sorte qu'une tâche (enfant) puisse dépendre d'une et une seule tâche (parent). C'est à dire que si une tâche est dépendante d'une autre et que celle-ci n'a pas l'état "validé", alors la tâche parente ne pourra être défini sur "validé".

    Voici le modèle recadré :
    Modèle

    Table tâches :

    <?php
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;

    class CreateTachesTable extends Migration {
    public function up()
    {
    Schema::create('taches', function(Blueprint $table) {
    $table->increments('id', true);
    $table->string('libelle', 150);
    $table->string('description', 250)->nullable();
    $table->string('infosComp', 200)->nullable();
    $table->datetime('dateLimite')->nullable();
    $table->boolean('avantOuApres')->nullable();
    $table->timestamps();
    $table->integer('positionnement_id')->unsigned()->nullable();
    $table->integer('etat_id')->unsigned()->default('1')->nullable();
    $table->integer('frequence_id')->unsigned()->nullable();
    });
    }

    public function down()
    {
    Schema::dropIfExists('taches');
    }
    }

    Modèle Tâche :

    <?php
    namespace App\Models;

    use Illuminate\Database\Eloquent\Model;

    class Tache extends Model
    {
    protected $table = 'taches';
    public $timestamps = true;
    protected $fillable = array('id', 'libelle', 'description', 'infosComp', 'dateLimite', 'avantOuApres', 'positionnement_id', 'etat_id', 'frequence_id');

    protected $casts = [
    'avantOuApres' => 'boolean',
    ];

    public function etat() {
    return $this->belongsTo('App\Models\Etat');
    }

    }

    Clés :

    <?php
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Eloquent\Model;

    class CreateForeignKeys extends Migration {
    public function up()
    {
    Schema::table('taches', function(Blueprint $table) {
    $table->foreign('etat_id')->references('id')->on('etats')
    ->onDelete('restrict')
    ->onUpdate('restrict');
    });
    [...]
    }
    public function down()
    {
    Schema::table('taches', function(Blueprint $table) {
    $table->dropForeign('taches_etat_id_foreign');
    });
    [...]
    }
    }

    Pouvez-vous m'aider svp ?

    Merci.

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

    Bonjour,

    Tu peux établir une relation hasOne d'un modèle sur lui-même :

    class Tache extends Model
    {

    ...

    public function tache()
    {
    return $this->hasOne('App\Models\Tache');
    }
  • Avatar de Pakito
    Membre depuis :
    07/02/2019
    Messages :
    8

    Bonjour,

    Je vous remercie pour votre réponse aussi rapide !

    Du coup j'ai fais comme vous avez dit, j'ai également crée une foreign Key dans la table Taches intitulé child_id.

    Lorsque je récupère ma liste de tâche voilà ce que j'obtiens si je lie une tâche (enfant) à une tâche (parente) :

    #original: array:13 [▼
    "id" => 1
    "libelle" => "Libelle de la tache 1"
    "description" => ""
    "infosComp" => ""
    "dateLimite" => "2018-12-24 18:30:00"
    "heureLimite" => null
    "avantOuApres" => null
    "created_at" => null
    "updated_at" => null
    "positionnement_id" => 1
    "etat_id" => 2
    "frequence_id" => 4
    "child_id" => 2
    ]

    Depuis la base de données je peux cliquer sur cette clé "child_id" qui me mène à la tâche parente n°2. Mais avec le controller, il est possible de faire de même ? Par exemple, avoir un tableau de cette child_id qui contient les infos de cette tâche parente du coup ? Comme si je pouvais déplier la FK tache_id avec toutes les infos..

    Ajout dans le modele tache :

    public function tache()
    [...]
    {
    return $this->hasOne('App\Models\Tache', 'child_id');
    }

    Ajout de la FK dans la table :

    $table->integer('child_id')->unsigned()->nullable();

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

    Salut,

    Il faut aussi créer la réciproque pour remonter au parent :

    public function tacheParent()
    {
    return $this->belongsTo('App\Models\Tache', 'child_id');
    }
  • Avatar de Pakito
    Membre depuis :
    07/02/2019
    Messages :
    8

    Super ! Un grand merci, j'ai récupéré tout ce dont je voulais c'est parfait !

    Merci pour votre aide !

    On peut même récupérer des "relations imbriquées" c'est génial :D !

    Je récupère toutes mes tâches avec leur tâches enfantes donc :
    $data = Tache::with('frequence', 'etat', 'positionnement', 'executants', 'postes', 'children')->get();

    L'Puis même leur propre relations (l'etat même de la tâche enfante) :
    $data = Tache::with('frequence', 'etat', 'positionnement', 'executants', 'postes', 'children**.etats**')->get();

    Bonne continuation et merci encore !

Vous ne pouvez pas répondre à ce sujet.