Slug isn’t changed with the name of the category

Steps to Reproduce:
I use this package cviebrock/eloquent-sluggable to create the slugs of the names of the categories. The slugs are created perfectly, but they aren’t changed, when I change the names of the categories.

Here is the model Category:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;

class Category extends Model
{
    use HasFactory;
    use Sluggable;

    protected $fillable = [
        'name',
        'slug'
    ];

    public function sluggable(): array
    {
        return [
            'slug' => [
                'source' => 'name'
            ]
        ];
    }

    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

Here is my CRUD component:

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Category;
use Cviebrock\EloquentSluggable\Services\SlugService;

class Categories extends Component
{
    public $slug, $name, $category, $category_id;
    public $isOpen = 0;

    public function render()
    {
        $categories  = Category::all();
        return view('admin.categories.cats', compact('categories'));
    }

    public function create()
    {
        $this->resetInputFields();
        $this->openModal();
    }

    public function openModal()
    {
        $this->isOpen = true;
    }

    public function closeModal()
    {
        $this->isOpen = false;
    }

    private function resetInputFields(){
        $this->name = '';
    }

    public function updatedTitle($name)
    {
        $this->slug = SlugService::createSlug(Category::class, 'name', $name);
    }

    public function store()
    {
        $this->validate([
            'name'   => 'required|max:30',
            'slug'   => 'required|max:30',
        ]);

        Category::updateOrCreate(['id' => $this->category_id], [
            'name'    => $this->name,
            'slug'    => $this->slug,
        ]);

        session()->flash('message',
            $this->category_id ? 'Категория успешно обновлена.' : 'Категория успешно создана.');

        $this->closeModal();
        $this->resetInputFields();
    }

    public function edit($id)
    {
        $category             =    Category::findOrFail($id);
        $this->category_id    =    $id;
        $this->slug           =    $category->slug;
        $this->name           =    $category->name;
        $this->openModal();
    }

    public function delete($id)
    {
        Category::find($id)->delete();
        session()->flash('message', 'Категория успешно удалена.');
    }
}

I have deleted the variable $slug from the component at all. It works the same way and the slug isn’t changed, when I rename the category. In the table in the db the name field is changed, but the slug field is the same.
Here is my migration:

public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->string('name', 30);
            $table->string('slug', 30);
            $table->timestamps();
        });
    }

Please, ideas🥺

Are you using the latest version of Livewire:
Yes

maybe you have to check this method…who is tittle? If you want to check for ‘name’ property’s changes you have to declared updatedName($name). Try this and tell me the result…hope this fix the issue

Hey, @nataly

Try to use Observers in your model it’s a lot better

    protected static function boot()
    {
        parent::boot();

        static::saving(function ($model) {
            $model->slug = make_slug($model->title);
        });
    }

You can set the option to re-slug when you update a model in cviebrock/eloquent-sluggable config file:

 return [
    'source'             => null,
    'method'             => null,
    'onUpdate'           => true, // Change to true
    'separator'          => '-',
    'unique'             => true,
    'uniqueSuffix'       => null,
    'includeTrashed'     => false,
    'reserved'           => null,
    'maxLength'          => null,
    'maxLengthKeepWords' => true,
    'slugEngineOptions'  => [],
];

Note: I have not tested this using livewire, but it works when updating models through Eloquent.

1 Like

Thank you, but it doesn’t work for me( the solution was so easy! Just to change the setting ‘onUpdate’ in the config file. Like @codebyray told​:pray::blush:

Thank you very much!

1 Like