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

mstnorris's avatar

Cast Pivot table value to Date

I have a User model and an Assignment model.

On the assignment_user table I have a couple of extra columns, one being date_completed which as it suggests contains the date that the assignment was completed.

When I access this in my view and call diffForHumans() it throws an error as it is being treated as a string and not a date as I am unable to cast it (I don't know where to put that behaviour).

How can I do this?

0 likes
9 replies
mstnorris's avatar

Thank you, how will that affect my relationships?

Currently both models belongsToMany.

martinbean's avatar

@mstnorris You could create a model for the pivot table, and then set up “has many through” relationships in your two other models instead:

class AssignmentUser {

    protected $dates = [
        'completed_at',
    ];

    public function user()
    {
        return $this->belongsTo('User');
    }

    public function assignment()
    {
        return $this->belongsTo('Assignment');
    }
}

class Assignment {

    public function users()
    {
        return $this->hasManyThrough('User', 'AssignmentUser');
    }
}

class User {

    public function assignments()
    {
        return $this->hasManyThrough('Assignment', 'AssignmentUser');
    }
}

I’ve only included the pertinent properties and methods.

1 like
mstnorris's avatar

Thank you, I think that has got me halfway there.

I am now getting this error (I'm sure it has to do with the fact that I need to explicitly define the column names).

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'assignment_user.id' in 'on clause' (SQL: select `assignments`.*, `assignment_user`.`assignment_id` from `assignments` inner join `assignment_user` on `assignment_user`.`id` = `assignments`.`assignment_user_id` where `assignment_user`.`assignment_id` = 1)

AssignmentUser

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class AssignmentUser extends Model {

    protected $table = 'assignment_user';
    
    protected $dates = [
        'date_completed'
    ];

    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function assignment()
    {
        return $this->belongsTo('App\Assignment');
    }

}

User

public function assignments()
{
    return $this->hasManyThrough('App\Assignment', 'App\AssignmentUser', 'assignment_id', 'user_id');
}

Assignment

public function assignments()
{
    return $this->hasManyThrough('App\User', 'App\AssignmentUser', 'user_id', 'assignment_id');
}

I'm sure I have messed up the arguments above.

mstnorris's avatar

@JarekTkaczyk can you shed any light on this? I think I have tried every combination and yet it still looks for an id column on the assignment_user table.

Does anyone else have any idea how this is doable?

JarekTkaczyk's avatar

@martinbean hasManyThrough works for chaing of hasOne/hasMany relations, while pivot is hasMany->belongsTo, so it can't work.

Also mind that custom pivot model is not the same as custom model for the pivot table - one must extend Pivot like below (and can't be instantiated just like that), other is just another model that you are using for the pivot table and it works exactly the same as any other model.

@mstnorris You need belongsToMany - nothing fancy there, just add withPivot('date_completed'). Then you just need also custom pivot model and custom newPivot method:

// User model - analogic method in the Assignment model
public function newPivot(Model $parent, array $attributes, $table, $exists)
{
    if ($parent instance of Assignment) {
        return new AssignmentUser($parent, $attributes, $table, $exists);
    }

    return parent::newPivot($parent, $attributes, $table, $exists);
}

the pivot model:

use Illuminate\Database\Eloquent\Relations\Pivot;

class AsignmentUser extends Pivot {
    $dates = ['date_completed'];
}

then this is going to use Carbon:

$assignment = Assignment::find($someId);
$user = $assignment->users()->first();
$user->pivot->date_completed; // Carbon instance
3 likes
mstnorris's avatar

@JarekTkaczyk where do I put this?

// User model - analogic method in the Assignment model
public function newPivot(Model $parent, array $attributes, $table, $exists)
{
    if ($parent instance of Assignment) {
        return new AssignmentUser($parent, $attributes, $table, $exists);
    }

    return parent::newPivot($parent, $attributes, $table, $exists);
}
mstnorris's avatar

Ok I thought as much but I am still getting an error

Call to a member function diffForHumans() on string which says that it isn't being treated as a Carbon instance.

I have added the code that you suggested above.

Please or to participate in this conversation.