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

andreich1980's avatar

Relation with a table itself with conditions?

I'm creating a game statistics app.

    // Activity.php
    public function killer()
    {
        return $this->belongsTo(Player::class, 'killer_id');
    }

    public function victim()
    {
        return $this->belongsTo(Player::class, 'victim_id');
    }

The Activity model has a created_at date.

I want to know victim's "age" for each piece of Activity.

The "age" is a difference between current created_at and created_at from the previous activity for the same victim.

What is the best way to do it?

I've been thinking about a relationship like

    public function age(Builder $query)
    {
        $query->hasOne(Activity::class, 'victim_id', 'victim_id')
            ->where('created_at', '<=', $this->created_at)
            ->latest()
            ->take(1);
    }

Is there any way to just count the difference between 2 created_at and not connect the whole model?

UPDATE:

I did it this way

    public function previous_death()
    {
        return $this->hasOne(Activity::class, 'victim_id', 'victim_id')
            ->where('created_at', '<', $this->created_at)
            ->latest()
            ->take(1);
    }

    public function age()
    {
        return $this->created_at->diffInMinutes($this->previous_death->created_at);
    }

Is this the best approach?

0 likes
5 replies
jcmargentina's avatar

I dont think there is an "automatic" way to do that, also ... I wouldnt create a realtionship, I would create a method called age, and retrieve the calculated age instead of a relationship

1 like
andreich1980's avatar
andreich1980
OP
Best Answer
Level 50

@jcmargentina Do you mean this?

public function age() {
    return Activity::where('victim_id', '=', $this->victim_id)
        ->where('created_at', '<', $this->created_at)
        ->latest()
        ->first()
        ->created_at->diffInMinutes($this->created_at);
}
2 likes

Please or to participate in this conversation.