Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

Je désire créer une bibiotheque manga sour Laravel

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Mangas extends Model {

    public $fillable = ['title_Manga_Fr','start_Date_Manga','end_Date_Manga','description_Manga_Fr','country_Manga','type_Manga','slug_Manga'];

    public function setTitleMangaFrAttribute($value){
            $this->attributes['title_Manga_Fr'] = strtoupper($value);
            $this->attributes['slug_Manga'] = str_slug($value, "-");

    }

}

Ce que je veux

lors d'une création d'un manga dans ma base de données, ajouter un slug à partir de son titre de façon automatisé

Ce que j'obtiens

J'arrive à modifier l'attribut title_Manga_Fr, mais pas l'attributs slug_Manga, qui revient dans une chaine de caractére vide

10 réponses


Zekura
Auteur
Réponse acceptée

Finalement, c'est bien la ligne de la view qui était le probléme. Je l'ai supprimé et ca marche.

Et j'ai également changer le setSlug

 public function setSlugMangaAttribute($value){
        if(empty($value)){
            $this->attributes['slug_Manga'] = " ";
            return $this->attributes['slug_Manga'] = Str::slug($this->attributes['title_Manga_Fr']);
        }
    }

Comme je débute sur Laravel, j'ai pas encore vue la partie observeur ^^ Malheuresement, comme je suis une formation vidéo Laravel 5.0 de Grafikart.fr, il y a pas cette partie la je crois

Bonjour,

Ton problème est normal. Ton mutateur setTitleMangaFrAttribute fonctionne seulement sur $this->attribute['title_Manga_Fr']. Pour slug_Manga, tu dois faire un autre mutateur :

<?php
public function setSlugMangaAttribute($value){
            $this->attributes['slug_Manga'] = str_slug($value, "-");
}

En gros, pour chaque valeur dans la colonne de ta table, tu dois créer un mutateur ou accesseur.

Zekura
Auteur

J'ai crée ce mutateur, mais l'attribut slug_manga reste toujours vide dans la base de donnée

Zekura
Auteur

J'ai essayé ca aussi, mais ca marche toujours pas

 public function setSlugMangaAttribute($value){
        if(empty($value)){
            $this->attributes['slug_Manga'] = str_slug($this->title_Manga_Fr, "-");
        }
    }

Dans ta bdd, tu enregistres bien le slug dans la colonne appelé slug_Manga ?

En ce qui me concerne, dans mon PostController, pour sauvegarder je fais :

<?php
public function store(ArticleRequest $request)
{
    $formData               = $request->all();
    $formData['user_id']    = $request->user()->id;
    $formData['slug']       = '';

    $article = Article::create($formData);

    alert()->success(
        'L\'article <strong>' . $article->title . '</strong> a bien été ajouté !',
        'Article ajouté !'
    )->html();

    return redirect()->route('admin.articles.index');
}

Et dans le modèle Post :

<?php
public function setSlugAttribute($value){
    if (empty($value)) {
        $this->attributes['slug'] = str_slug($this->title, '-');
    }
}

PostController appelle setSlugAttribute dans le modèle Post seulement si tu appelles l'attribut lors de la sauvegarde. Vu qu'il n'y a pas d'input slug (on veut le créer à partir du titre), il faut la déclarer vide pour que le modèle Post la trouve.

Pour résumer, setSlugAttribute marche seulement si un input slug existe ou si tu crées un slug vide manuellement avant de sauvegarder avec Post::create($data).

Zekura
Auteur

Dans mon MangasController j'ai ca

public function store(MangasRequest $request)
    {
        Mangas::create($request->only('title_Manga_Fr','start_Date_Manga','end_Date_Manga','description_Manga_Fr','country_Manga','type_Manga','slug_Manga'));
        return redirect(action('MangasController@index'))->with('success', 'Le manga a bien été crée');
    }

Je dois faire alors le $formData juste avant Mangas::create ?

PS: Dans la view, j'ai mis le slug_Manga en hidden, je sais pas si ca à une incidence ou pas

Tu peux me montrer l'input slug_Manga en hidden stp ?

Zekura
Auteur
{!! Form::hidden('slug_Manga', ' ') !!}

Hello,
Comme l'explique jeremyB si pendant la sauvegarde tu n'as pas de clef slug_Manga ta méthode set ne sera jamais appellé donc à vérifier .
Par contre de devoir set la valeur du slug par défaut dans le controller je trouve ça moyen .

Au lieu de faire un setSlugMangaAttribute() dans ton model je partirai plutôt sur cette solution :
https://laravel.com/docs/5.5/eloquent#observers

en gros il faut créer un observer pour ton model en question, et sur l'event saving

tu viens faire ta vérification :

    public function saving(Manga $manga)
    {
           $manga->slug_Manga =str_slug($manga->title_Manga_Fr, "-");
    }

@Amilti : je connaissais la partie observers pour faire un système où tu comptes le nombre d'articles dans une catégorie par exemple. Mais bizarrement, je ne l'aurais pas fait pour le slug.. Va comprendre.

Par contre, quelle utilité de continuer à utiliser des setters ailleurs ? Utilisation hors eloquent (bdd donc) ?