2015-06-01 17 views
7

Tôi đang cố gắng tìm hiểu laravel 5 với sự trợ giúp của this wondefull website. Đối với mô hình hoạt động của tôi, tôi muốn tạo các slugs trước khi lưu một cơ sở dữ liệu vào cơ sở dữ liệu của mình, vì vậy tôi đã tạo ra mô hình sau đây.Laravel tạo slug trước khi lưu

<?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 , "-"); 
    } 
    //  
} 

Nhưng khi tôi lưu một đối tượng với sự giúp đỡ của các mô hình Hoạt động sên không được điền, tôi đã cố gắng thay đổi nó đến $ this-> thuộc tính [ 'title'] = "test" để thử nghiệm nhưng nó didnt chạy. Ngoài ra tôi đã thử thêm tham số $ title, $ slug vào setSlugAttribute() nhưng nó không giúp được gì.

Tôi đang làm gì sai và ai đó có thể giải thích tham số được sử dụng trong một số ví dụ cho setSomeAttribute ($ whyParameterHere).

Lưu ý: có trường sên trong cơ sở dữ liệu của tôi.

Theo đề nghị của user3158900 Tôi đã thử:

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

Điều này làm cho lĩnh vực tiêu đề của tôi trống rỗng nhưng tiết kiệm sên cách tôi muốn nó, tại sao là $ this-> tiêu đề trống sau đó? Nếu tôi xóa $ this-> title = $ title; cả hai tiêu đề và slug đều trống rỗng

Trả lời

13

Tôi tin rằng điều này không hoạt động vì bạn không cố gắng đặt thuộc tính slug để chức năng không bao giờ bị tấn công.

Tôi khuyên bạn nên đặt $this->attributes['slug'] = ... trong chức năng setTitleAttribute() của bạn để nó chạy bất cứ khi nào bạn đặt tiêu đề.

Nếu không, giải pháp khác sẽ là tạo sự kiện để lưu cho mô hình của bạn sẽ đặt nó ở đó.

Edit: Theo ý kiến, nó cũng cần thiết để thực sự thiết lập các thuộc tính tiêu đề trong chức năng này cũng ...

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

chỉnh sửa câu hỏi với sự giúp đỡ của bạn. nó để trống tiêu đề vì một lý do nào đó. nếu tôi xóa $ this-> title = $ title; cả hai đều trống. Tôi vẫn không hiểu thông số mặc dù –

+0

$ this-> title = $ title; nên là $ this-> attributes ['title'] hoạt động tốt ngay bây giờ! –

+0

Sử dụng thư viện Sluggable –

2

Bạn có thể sử dụng gói này mà tôi sử dụng https://github.com/cviebrock/eloquent-sluggable hoặc kiểm tra cách nó áp dụng một người quan sát về mô hình tiết kiệm và cách tạo ra một Slug độc đáo.

+0

str_slug ($ this-> tiêu đề, "-"); hoạt động tốt. –

1

Bạn muốn thiết lập các sên dựa trên các tiêu đề khi thuộc tính tiêu đề đang được bộ.

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 

Một lựa chọn khác là sử dụng một ModelObserver và lắng nghe những tiết kiệm sự kiện. Điều này sẽ cho phép bạn tạo slug ngay trước khi mô hình được ghi vào cơ sở dữ liệu.

class ActivityObserver { 

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

Trong cả hai trường hợp, bạn có thể muốn thêm một số logic để kiểm tra nếu con sên đã tồn tại trong DB, thêm số gia tăng nếu có. tức là foo-bar-baz-2. Nơi an toàn nhất cho lôgic này sẽ nằm trong ModelObserver vì nó được thực hiện ngay trước hành động ghi.

4

Một cách để thực hiện việc này là móc vào model events. Trong trường hợp này, chúng tôi muốn tạo một slug khi tạo.

/** 
* 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; 

    }); 

} 

Bạn cũng sẽ cần phải thêm dòng sau vào danh sách của bạn ứng dụng các bí danh (app.php):

'Str' => Illuminate\Support\Str::class, 
Các vấn đề liên quan