jeudi 16 novembre 2017

Attribute not saving to Model in boot method

When creating a new model instance, the 'slug' attribute is not being saved. I checked that the creating event in the boot method is being called. However, in tinker, I can see that there is no 'slug' key in the attributes. What gives? For the life of me, I can't find my mistake.

Tinker:

App\Models\TicketType::create(['title'=>'My title']);

Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1364 Field 'slug' doesn't have a default value (SQL: insert into `ticket_types` (`title`, `updated_at`, `created_at`) values (my title, 2017-11-16 08:13:17, 2017-11-16 08:13:17))'

TicketType.php

namespace App\Models;

use App\Models\Abstracts\TypeModelAbstract;
use App\Models\Interfaces\TypeModelInterface;
use App\Traits\HasSlug;

class TicketType extends TypeModelAbstract implements TypeModelInterface {

    use HasSlug;

    protected $fillable = [
        'title',
        'slug',
        ...
    ];

    ...

    public static function boot() {

        parent::boot();

        static::creating(function ($item) {
            $item->sluggable();
            \Log::debug('slug is ' . $item->slug, $item->attributes);
            // Here $item->slug is correct, but the slug is not in the attributes array
        });
    }

HasSlug.php

namespace App\Traits;

use Illuminate\Support\Facades\Cache;

trait HasSlug {

    public function sluggable() {
        if (!$this->getSlug()) {
            $slug = $this->buildSlug();
            $this->setSlug($slug);
        }
        return $this;
    }

    public function refreshSlug() {
        $this->setSlug($this->buildSlug());
        return $this;
    }

    protected function setSlug($slug) {
        // $save_to = static::$sluggable_save_to_attribute ?? 'slug'; -- PHP bug fixed in 7.0.19 and  7.1.5
        $save_to = isset(static::$sluggable_save_to_attribute) ? static::$sluggable_save_to_attribute : 'slug';
        $this->attributes[$save_to] = $slug;
        // $this->setAttribute($save_to, $slug);
        return $this;
    }

    /**
     * @return \Eloquent
     */
    public function getSlug() {
        // $save_to = static::$sluggable_save_to_attribute ?? 'slug'; -- PHP bug fixed in 7.0.19 and  7.1.5
        $save_to = isset(static::$sluggable_save_to_attribute) ? static::$sluggable_save_to_attribute : 'slug';
        // return $this->getAttribute($save_to);
        return $this->$save_to;
    }

    /**
     * @return string
     */
    protected static function getRand() {
        $length = 11;
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $size = strlen($chars);
        $str = '';
        for ($i = 0; $i < $length; $i++) {
            $str .= $chars[rand(0, $size - 1)];
        }
        return $str;
    }

    /**
     * @param string $str;
     * @return string;
     */
    protected function mod($str) {
        // if (static::$sluggable_uppercase ?? false ) {  -- PHP bug fixed in 7.0.19 and  7.1.5
        $uppercase = isset(static::$sluggable_uppercase) ? static::$sluggable_uppercase : false;
        if ( $uppercase ) {
            return strtoupper($str);
        } else {
            return $str;
        }
    }

    /**
     * @return string
     */
    protected function buildSlug() {
        // $attr = static::$sluggable_build_from_attribute ?? 'title'; -- PHP bug fixed in 7.0.19 and  7.1.5
        $attr = isset(static::$sluggable_build_from_attribute) ? static::$sluggable_build_from_attribute : 'title';
        $string = $attr && $this->$attr ? $this->$attr : static::getRand();
        return $this->bestSlugFrom($string);
    }

    /**
     * @param string $string
     * @return string
     */
    public function bestSlugFrom($string) {
        $original = $slug = $this->mod(static::sluggify($string));
        $i = 1;
        while (static::findBySlug($slug, true)) {
            $slug = $original . '-' . $i;
            $i++;
        }
        return $slug;
    }

    /**
     * Sluggify a string
     * @param string $text
     * @return string
     */
    public static function sluggify($text) {
        $text = str_replace(array('#', 'ω'), array(' sharp', ' omega'), $text); // replace non letter or digits by -
        return str_slug($text);
    }

    /**
     * Get a model by the slug
     * @param string $slug
     * @param bool $includeTrashed
     * @return static
     */
    public static function findBySlug($slug, $includeTrashed = false ) {
        // $slugAttr = static::$sluggable_save_to_attribute ?? 'slug'; -- PHP bug fixed in 7.0.19 and  7.1.5
        $slugAttr = isset(static::$sluggable_save_to_attribute) ? static::$sluggable_save_to_attribute : 'slug';
        return Cache::remember( get_called_class() . "_bySlug_{$slug}_{$includeTrashed}", 1, function () use ($slug, $includeTrashed, $slugAttr) {
            $q = static::where($slugAttr ?? 'slug', $slug);
            if ( $includeTrashed && method_exists(get_called_class(), 'bootSoftDeletingTrait') ) {
                /* Make sure the model has soft deletes before calling this method */
                $q->withTrashed();
            }
            return $q->first();
        });
    }

}



from Newest questions tagged laravel-5 - Stack Overflow http://ift.tt/2z5YqHt
via IFTTT

Aucun commentaire:

Enregistrer un commentaire