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

gidaban79's avatar

Strange behoviur with slug

Some code :)

My jsonResource

class ThreadResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'slug' => $this->slug,
            'content' => $this->content,
            'created_at' => $this->created_at,
            'views' => $this->views,
            'short_content' => $this->short_content,
            'replies_count' => $this->replies_count,

            'creator' => new UserResource($this->whenLoaded('user')),
            'channel' => new ChannelResource($this->whenLoaded('channel')),
            'replies' => ReplyResource::collection($this->whenLoaded('replies')),
        ];
    }
}

I am using this resoruce to send response from laravel to inertiajs, /forum/channels/kitchen-fitters-chat/whats-your-goto-solid-surface-147970 and i am gettings links like that after clink on this link all works well, however i am geting different slug as response even i am using same jsonResponse."slug": "whats-your-goto-solid-surface-1" to slug is added id or record instead of full slug ?

Any ideas what is going on ?

0 likes
6 replies
tykus's avatar

On the underlying Model, what defines the slug?

gidaban79's avatar

I am using observer to 'generate' slug.

    public function creating(Discussion $discussion)
    {
        $discussion->title = Str::title($discussion->title);
        $discussion->user_id = auth()->id();
        $discussion->slug = Str::slug($discussion->title . ' ' . mt_rand(100000, 999999));
    }

and slug is saved proper 'test-244353' but in inertia i am getting 'test-idOfRecord'

tykus's avatar

@gidaban79 is there any accessor for the slug; I don't see how the suffix should come from the ID based on the code you have shared?

gidaban79's avatar

@tykus model

<?php
/*
 * Copyright (c)  DeveloperZONE 2022.
 */

namespace App\Models;

use App\Filters\ForumFilters;
use Auth;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Str;

class Discussion extends Model
{
    protected $fillable = [
        'title',
        'content',
        'user_id',
        'channel_id',
        'slug',
        'count_replies',
    ];

    protected $appends = ['short_content'];

    public function channel(): BelongsTo
    {
        return $this->belongsTo(Channel::class);
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }

    public function replies(): HasMany
    {
        return $this->hasMany(Reply::class);
    }

    public function watchers(): HasMany
    {
        return $this->hasMany(Watcher::class);
    }

    public function isBeingWatchedByAuthUser(): bool
    {
        $id = Auth::id();
        $watchers_ids = [];
        foreach ($this->watchers as $watcher) {
            $watchers_ids[] = $watcher->user_id;
        }

        if (in_array($id, $watchers_ids, true)) {
            return true;
        }

        return false;
    }

    public function scopeFilter($query, ForumFilters $filters)
    {
        return $filters->apply($query);
    }

    public function getShortContentAttribute(): string
    {
        return Str::limit(strip_tags($this->content), 100);
    }

    public function attachFiles($files): Model
    {
        return $this->files()->create($files);
    }

    public function files(): HasMany
    {
        return $this->hasMany(ForumFile::class, 'discussion_id', 'id');
    }

    public function scopeClosed(Builder $query): Builder
    {
        return $query->where('is_closed', true);
    }

    public function createdAt(): Attribute
    {
        return Attribute::make(
            get: static fn ($value) => Carbon::parse($value)->diffForHumans(),
        );
    }
}

Contoller

    public function index(Channel $channel, ForumFilters $filters)
    {
        $discussions = Discussion::withCount('replies')->with('channel')->filter($filters);
        if ($channel->exists) {
            $discussions->where('channel_id', $channel->id);
        }
        

        return Inertia::render('Forum/Index', [
            'threads' => ThreadResource::collection($discussions->paginate(10)),
        ]);
    }

Wich return collection

"data": [
{
"id": 1,
"title": "Whats Your Goto Solid Surface?",
"slug": "whats-your-goto-solid-surface-147970",
"content": "<p>My goto is Mirostone. It's softer than Mistral. Great fitting kit.<br>I've fitted Pietra / Pietra Gold, Mirostone, Mistral and various chipboard core resin worktops in the past.<br>What's your goto and why?</p>",
"created_at": "1 year ago",
"views": 552,
"short_content": "My goto is Mirostone. It's softer than Mistral. Great fitting kit.I've fitted Pietra / Pietra Gold,...",
"replies_count": 1,
"channel": {
"title": "Kitchen Fitters Chat",
"slug": "kitchen-fitters-chat"
}
}```

and show method

public function show(Channel $channel, Discussion $discussion)
{

    $discussion->increment('views');

    
    return Inertia::render('Forum/Show', [
        'discussion' => new ThreadResource($discussion->loadCount('replies')->load('channel')->load('replies')->load('user')),
        'replies' => fn () => RepliesResource::collection($discussion->replies()->with('user')->withCount('likes')->paginate(config('custom.comments.paginate'))),
    ]);
}```

return

{
"data":{"id":1,"title":"Whats Your Goto Solid Surface?","slug":"whats-your-goto-solid-surface-1","content":"
My goto is Mirostone. It's softer than Mistral. Great fitting kit.
I've fitted Pietra / Pietra Gold, Mirostone, Mistral and various chipboard core resin worktops in the past.
What's your goto and why?
gidaban79's avatar

Okay what i just spotted

$discussion->increment('views');

if i comment it slugs works okay.

gidaban79's avatar

TBH i am lil bit lost

        DB::table('discussions')
            ->where('id', $discussion->id)
            ->increment('views');

It works, however

$discussion->increment('views');

Update slug in DB

Please or to participate in this conversation.