Salut, je suis en train de regarder la formation laravel et notamment la partie sur les relations belongsToMany.

Mon soucis est que je n'arrive pas à récupérer les tags associés (pourtant ceux ci sont présents dans la base de donnée) . J'ai regardé encore et encore la partie du code pour vérifier mais je ne pense vraiment pas faire d'erreur sur ce point :/

Voici mon code au cas où :

<div class="form-group">
    {!! Form::label('tag_list', 'Tags', ['class' => 'control-label col-lg-2']) !!}
    <div class="col-lg-10">
        {!! Form::select('tag_list[]', $tags, null, ['class' => 'form-control', 'multiple']) !!}
    </div>
</div>

Post (model) :

/**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function tags()
    {
        return $this->belongsToMany('App\Tag');
    }

    /**
     * @return mixed
     */
    public function getTagListAttribute()
    {
        return $this->tags->lists('id');
    }

    /**
     * @param $value
     * @return array
     */
    public function setTagsListAttribute($value)
    {
        return $this->tags()->sync($value);
    }

PostsController :

public function edit($id)
    {
        $post = Post::with('category')->findOrFail($id);
        $tags = Tag::lists('name', 'id');
        $categories = Category::lists('name', 'id');

        return view('posts.edit', compact('post', 'categories', 'tags'));
    }

9 réponses


Alexandre #lbac
Auteur
Réponse acceptée

J'ai finalement résolu mon problème. Pour que cela fonctionne il fallait rajouter la méthode toArray() à ma sélection des tags. Du coup ça marche parfaitement et la méthode avec les attributs fonctionne également :)

Merci pour ton aide en tout cas spiker :)

Dans ce cas là faut que tu envois manuellement la liste des tags au select (là ou tu as mis null)

Hello,

Si tu veux récuperer les tags lié à ton post, il faut modifier ta requète:

$tags = $post->tags()->lists('name', 'id');

Normalement ça devrait marcher, je n'ai pas eu le temps de tester.

Le plus surprenant c'est que même en les récupérant manuellement, ils ne sont pas sélectionnés dans mon select :/

Pourtant lorsque je fais une die and debug j'obtiens bien les tags associés à mon article

dd($post->tags()->lists('name', 'id'));
Collection {#165 ▼
  #items: array:2 [▼
    1 => "chat"
    2 => "chien"
  ]
}

En revanche si je place ce code dans mon select, aucun tag n'est sélectionné

Ah, si tu veux faire en sorte de pré-selectionner les tags lié à ton post, il faut faire comme ceci:

{!! Form::select('tag_list[]', $select, $tags, ['class' => 'form-control', 'multiple']) !!}

$select correspond à tous les tags disponnible.
$tags correspond aux tags de ton post

Donc:

public function edit($id)
    {
        $post = Post::with('category')->findOrFail($id);
        $tags = Tag::lists('name', 'id');
        $postTag = $post->tags()->lists('name', 'id');
        $categories = Category::lists('name', 'id');

        return view('posts.edit', compact('post', 'categories', 'tags', 'postTag'));
    }

    {!! Form::select('tag_list[]', $tags, $postTag, ['class' => 'form-control', 'multiple']) !!}

Le troisième argument d'un select est le/les options pré-selectionné de celui-ci.

J'ai oublié de précisé que je récupère intialement les données avec la méthode Form::model($post);
Mais j'ai déjà tenté un code similaire au tien et sans succès :/

J'ai quand même testé ton codé pour être sûr, et même résultat, les tags ne sont pas sélectionnés :/

Pourtant dans tinker :

>>> $post->tags()->lists('id', 'name');
=> Illuminate\Support\Collection {#697
     all: [
       "chat" => 1,
       "chien" => 2,
     ],
   }

Tu peux me faire un dd() de $tags et $postTag ? stp

Oui bien sûr :

$tags :

Collection {#167 ▼
  #items: array:4 [▼
    1 => "chat"
    2 => "chien"
    3 => "castor"
    4 => "renard"
  ]
}

$postTag :

Collection {#172 ▼
  #items: array:2 [▼
    1 => "chat"
    2 => "chien"
  ]
}

Je viens de comparer avec un système qui marche de mon côté:

Collection {#319 ▼
  items: array:3 [▼
    1 => "Programmation"
    2 => "Cuisine"
    3 => "Hacking"
  ]
}
array:1 [▼
  0 => 3
]

Dans ce cas la, "Hacking" sera pré-selectionné. Respecte la même forme pour les tableay et ça devrait aller. (joue avec les 'id', 'name' dans la fonction list)