Laravel generate slug before save
You could use this package which I use https://github.com/cviebrock/eloquent-sluggable or check how it applies an observer on the model saving and how it generates a unique Slug, then do the same.
One way to accomplish this would be to hook into model events. In this instance, we want to generate a slug upon creating.
/**
* Laravel provides a boot method which is 'a convenient place to register your event bindings.'
* See: https://laravel.com/docs/4.2/eloquent#model-events
*/
public static function boot()
{
parent::boot();
// registering a callback to be executed upon the creation of an activity AR
static::creating(function($activity) {
// produce a slug based on the activity title
$slug = \Str::slug($news->title);
// check to see if any other slugs exist that are the same & count them
$count = static::whereRaw("slug RLIKE '^{$slug}(-[0-9]+)?$'")->count();
// if other slugs exist that are the same, append the count to the slug
$activity->slug = $count ? "{$slug}-{$count}" : $slug;
});
}
You will also need to add the following to your applications list of aliases (app.php):
'Str' => Illuminate\Support\Str::class,
You got 2 ways:
1. Add localy in your controller method this line:
$request['slug'] = Str::slug($request->title);
Example:
//use Illuminate\Support\Str;
public function store(Request $request)
{
$request['slug'] = Str::slug($request->title);
auth()->user()->question()->create($request->all());
return response('Created!',Response::HTTP_CREATED);
}
2. Add it in your model to check it every save in db
//use Illuminate\Support\Str;
protected static function boot() {
parent::boot();
static::creating(function ($question) {
$question->slug = Str::slug($question->title);
});
}
Example:
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
use App\User;
use Illuminate\Support\Str;
class Question extends Model
{
protected static function boot() {
parent::boot();
static::creating(function ($question) {
$question->slug = Str::slug($question->title);
});
}
//The rest of methods
In each way you have to add this code before class declaration:
use Illuminate\Support\Str;
I believe this isn't working because you aren't trying to set a slug attribute so that function never gets hit.
I'd suggest setting $this->attributes['slug'] = ...
in your setTitleAttribute()
function so it runs whenever you set a title.
Otherwise, another solution would be to create an event on save for your model which would set it there.
Edit: According to comments, it's also necessary to actually set the title attribute in this function as well...
public function setTitleAttribute($value)
{
$this->attributes['title'] = $value;
$this->attributes['slug'] = str_slug($value);
}