Laravel在保存之前产生slu ..

时间:2015-06-01 20:23:05

标签: php laravel laravel-5

我试图在this wondefull website的帮助下学习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 , "-");
    }
    //    
}

但是当我在活动模型slug的帮助下保存对象时,我没有填充,我尝试将其更改为$ this-&gt; attributes [&#39; title&#39;] =&#34; test&#34;用于测试,但它没有运行。此外,我尝试将参数$ title,$ slug添加到setSlugAttribute(),但它没有帮助。

我做错了什么,有人可以解释setSomeAttribute($ whyParameterHere)的一些示例中使用的参数。

注意:我的数据库中有一个slug字段。

根据user3158900的建议,我尝试过:

public function setTitleAttribute($title){
    $this->title = $title;
    $this->attributes['slug'] = str_slug($this->title , "-");
}
//

这使得我的标题字段为空但是以我想要的方式保存了slug,为什么$ this-&gt;标题为空呢? 如果我删除$ this-&gt; title = $ title;标题和slug都是空的

5 个答案:

答案 0 :(得分:20)

我认为这不起作用,因为你没有尝试设置一个slug属性,所以函数永远不会被击中。

我建议在$this->attributes['slug'] = ...函数中设置setTitleAttribute(),以便在设置标题时运行。

否则,另一种解决方案是为您的模型创建一个保存事件,并将其设置在那里。

编辑:根据评论,还需要在此功能中实际设置title属性...

public function setTitleAttribute($value)
{
    $this->attributes['title'] = $value;
    $this->attributes['slug'] = str_slug($value);
}

答案 1 :(得分:6)

实现这一目标的一种方法是挂钩model events。在这种情况下,我们希望在创建

时生成一个slug
/**
 * 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;

    });

}

您还需要将以下内容添加到别名的应用程序列表(app.php)中:

'Str' => Illuminate\Support\Str::class,

答案 2 :(得分:2)

你可以使用我使用https://github.com/cviebrock/eloquent-sluggable的这个包,或者检查它如何在模型保存中应用观察者以及如何生成一个独特的Slug,然后再做同样的事情。

答案 3 :(得分:1)

您希望在设置title属性时根据标题设置slug。

class ActivityObserver {

    public function saving($activity) 
    {
        $activity->slug = str_slug($activity->title);
    }
}

另一种选择是使用ModelObserver并收听保存事件。这将允许您在将模型写入数据库之前生成slug。

3
1 0 1
0 1 1
1 0 1
5
1 1 1 0 0
1 1 0 1 1
1 0 1 0 1
0 1 0 1 0
0 1 1 1 1
3
1 0 0
0 1 0
0 0 1
2
1 1
1 1
0

在这两种情况下,您可能都想添加一些逻辑来测试数据库中是否已存在slug,如果确实存在,则添加一个递增数字。即 foo-bar-baz-2 。这个逻辑最安全的地方是在ModelObserver中,因为它在写操作之前立即执行。

答案 4 :(得分:0)

您有2种方法:

1。在此行的控制器方法中添加语言环境:

$request['slug'] = Str::slug($request->title);

示例:

//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。将其添加到模型中,以检查是否保存在数据库中

//use Illuminate\Support\Str;

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

    static::creating(function ($question) {
        $question->slug = Str::slug($question->title);
    });
}

示例:

<?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

必须通过每种方式在类声明之前添加以下代码:

use Illuminate\Support\Str;