Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

CamKem's avatar
Level 10

Help with setting up an short text excerpt in my model

Hello, I am trying to set up a function that will take the input from the body text and create an excerpt that is automatically saved in the db table.

I want it to work similar to the sluggable package that takes the title & turns it into a slug, however as this is a much simpler function I am using the Str helper instead of a external package.

this is my code in the model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Support\Str;

class Post extends Model
{
    use HasFactory, Sluggable;
    
    protected $fillable = [
        'title',
        'body',
        'published_at',
    ];

    public function sluggable(): array
    {
        return [
            'slug' => [
                'source' => 'title'
            ]
        ];
    }

    public function excerpt()
    {
        return Str::limit($this->body, 100);
    }
}

In PhpStorm the excerpt function is grey denoting that it is not being used anywhere in the project, which is why I assume when I try to use tinker to enter and save data it is telling me that the excerpt field doesn't have a default value.

I am new to php & laravel so please bear with me & help me to work out how to return this function properly so that it saves the excerpt when I run Post::create with the title & body in tinker.

0 likes
5 replies
CamKem's avatar
Level 10

@Sinnbeck Hi, thanks for the response.

I have changed my model to the following

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Support\Str;

class Post extends Model
{
    use HasFactory, Sluggable;

    protected $fillable = [
        'title',
        'slug',
        'excerpt',
        'body',
        'published_at',
    ];

    public function sluggable(): array
    {
        return [
            'slug' => [
                'source' => 'title'
            ]
        ];
    }

    protected function excerpt(): Attribute
    {
        return Attribute::make(
            'body',
            fn () => Str::limit($this->body, 100)
        );
    }

}

However when running the following code on tinker I get the following errors

> Post::create(['title' => 'My Fourth Post', 'body' => 'sfgdsgdfgdg fdgdfggs gdfsg fdsg dfsg sdfgfdg dfg dfg dfgdf gdf g dsfg dfg dfg dfsg fgh rthrt hr efgew few freg erg eqrg we fwr g qreg ewf rweef wef wef wef ew f ewf wef weq fwe f wef ew fwe fewf ewf ewf ew f ewf wef ewf we f wef ewrtghtgr erf qerwgt ghtr greg gq erge e qgr eger qgr gq rg reg  erg erg  reg r gr egre gre ggre gre g reg regregerg reg regqergrtehgtyhrg  regrthrt']);
[!] Aliasing 'Post' to 'App\Models\Post' for this Tinker session.

   Illuminate\Database\QueryException  SQLSTATE[HY000]: General error: 1364 Field 'excerpt' doesn't have a default value (SQL: insert into `posts` (`title`, `body`, `slug`, `updated_at`, `created_at`) values (My Fourth Post, sfgdsgdfgdg fdgdfggs gdfsg fdsg dfsg sdfgfdg dfg dfg dfgdf gdf g dsfg dfg dfg dfsg fgh rthrt hr efgew few freg erg eqrg we fwr g qreg ewf rweef wef wef wef ew f ewf wef weq fwe f wef ew fwe f ewf ewf ewf ew f ewf wef ewf we f wef ewrtghtgr erf qerwgt ghtr greg gq erge e qgr eger qgr gq rg reg  erg erg  reg r gr egre gre ggre gre g reg regregerg reg regqergrtehgtyhrg  regrthrt, my-fourth-post, 2023-01-21 09:25:57, 2023-01-21 09:25:57)).

So it seems it still isn't taking the body and returning an excerpt to the model, I have read through on the accessors & mutators but this is the first to I have run into them so I am unfamiliar.

I want it to automatically add the trimmed down excerpt into the db in tinker like the slug is doing.

tisuchi's avatar
tisuchi
Best Answer
Level 70

@camkem I also suggest to use Mutator as @sinnbeck suggested. It might be straight forward.

For example-

class Post extends Model
{
    use HasFactory, Sluggable;
    
    protected $fillable = [
        'title',
        'body',
        'excerpt',
        'published_at',
    ];

    public function sluggable(): array
    {
        return [
            'slug' => [
                'source' => 'title'
            ]
        ];
    }

    public function setBodyAttribute($value)
    {
        $this->attributes['body'] = $value;
        $this->attributes['excerpt'] = Str::limit($value, 100);
    }
}
CamKem's avatar
Level 10

@tisuchi Yes, thanks this code worked well, I was a fair way off with my guess above, thanks for the code.

CamKem's avatar
Level 10

@tisuchi However, I will look more into the accessors & mutators as this is something I need to learn.

Please or to participate in this conversation.