php Laravel 在保存前生成 slug
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30582600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel generate slug before save
提问by Sven van den Boogaart
Im trying to learn laravel 5 with help of this wondefull website. For my activity model I want to generate slugs before I save one to my database so I've created the following model.
我试图在这个奇妙的网站的帮助下学习 laravel 5 。对于我的活动模型,我想在将一个 slug 保存到我的数据库之前生成一个,所以我创建了以下模型。
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Activity extends Model {
protected $table = 'activitys';
protected $fillable = [
'title',
'text',
'subtitle'
];
// Here I want to auto generate slug based on the title
public function setSlugAttribute(){
$this->attributes['slug'] = str_slug($this->title , "-");
}
//
}
But when I save an object with help of the Activity model slug is not filled, i tried changing it to $this->attributes['title'] = "test" for testing but it didnt run. Also I tried adding parameters $title, $slug to setSlugAttribute() but it didnt help.
但是当我在 Activity 模型 slug 未填充的帮助下保存对象时,我尝试将其更改为 $this->attributes['title'] = "test" 进行测试,但它没有运行。我也尝试添加参数 $title, $slug 到 setSlugAttribute() 但它没有帮助。
What am I doing wrong and could someone explain the parameter that is used in some examples for setSomeAttribute($whyParameterHere).
我做错了什么,有人可以解释在 setSomeAttribute($whyParameterHere) 的一些示例中使用的参数。
Note : there is a slug field in my database.
注意:我的数据库中有一个 slug 字段。
As suggested by user3158900 I've tried :
正如 user3158900 所建议的,我尝试过:
public function setTitleAttribute($title){
$this->title = $title;
$this->attributes['slug'] = str_slug($this->title , "-");
}
//
This makes my title field empty but saves the slug the way I want it, why is $this->title empty then ? If I remove $this->title = $title; both title and slug are empty
这使我的标题字段为空,但以我想要的方式保存 slug,为什么 $this->title 为空呢?如果我删除 $this->title = $title; title 和 slug 都是空的
回答by user1669496
I believe this isn't working because you aren't trying to set a slug attribute so that function never gets hit.
我相信这是行不通的,因为您没有尝试设置 slug 属性,以便该函数永远不会被击中。
I'd suggest setting $this->attributes['slug'] = ...
in your setTitleAttribute()
function so it runs whenever you set a title.
我建议$this->attributes['slug'] = ...
在您的setTitleAttribute()
函数中进行设置,以便在您设置标题时运行。
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);
}
回答by Dilworth
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):
您还需要将以下内容添加到您的应用程序别名列表 (app.php):
'Str' => Illuminate\Support\Str::class,
回答by Mahmoud Zalt
You could use this package which I use https://github.com/cviebrock/eloquent-sluggableor check how it applies an observer on the model saving and how it generates a unique Slug, then do the same.
您可以使用我使用的这个包https://github.com/cviebrock/eloquent-sluggable或检查它如何在模型保存中应用观察者以及它如何生成唯一的 Slug,然后执行相同的操作。
回答by Piotr
You got 2 ways:
你有两种方法:
1. Add localy in your controller method this line:
1. 在您的控制器方法中添加 localy 这一行:
$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
2.将它添加到您的模型中以在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;
回答by Collin James
You want to set the slug based off the title when the title attribute is being set.
您希望在设置 title 属性时根据标题设置 slug。
public function setTitleAttribute($value)
{
$this->attributes['title'] = $value;
$this->attributes['slug'] = str_slug($value);
}
/// Later that same day...
$activity->title = 'Foo Bar Baz';
echo $activity->slug; // prints foo-bar-baz
Another alternative would be to use a ModelObserverand listen to the savingevent. This will allow you to generate the slug right before the model is written to the database.
另一种选择是使用ModelObserver并侦听保存事件。这将允许您在模型写入数据库之前生成 slug。
class ActivityObserver {
public function saving($activity)
{
$activity->slug = str_slug($activity->title);
}
}
In both cases you probably want to add some logic to test if the slug already exists in the DB, adding an incrementing number if it does. ie foo-bar-baz-2. The safest place for this logic would be in the ModelObserver as it is executed immediately prior to the write action.
在这两种情况下,您可能想要添加一些逻辑来测试 slug 是否已经存在于数据库中,如果存在则添加一个递增的数字。即foo-bar-baz-2。这个逻辑最安全的地方是在 ModelObserver 中,因为它在写操作之前立即执行。