I am encountering an issue on Laravel, an exception is thrown because of an "undefined" created_at column on one of the database tables (but not the pivot table). The accessor in question is returning a human friendly format for the date. The data is sent to the client as JSON. Here are the tables:

class Link extends Model
{
    use HasFactory;

    protected $primaryKey='id';
    protected $table='links';
    protected $perPage=24;

    protected $appends = [
        'human_friendly',
        'slug',
    ];

    protected $fillable = [
        'url',
        'active',
        'slug',
        'title',
        'site_name',
        'twitter_site',
        'description',
        'locale'
    ];

    protected $hidden = [];

    protected $casts = [
        'active' => 'boolean',
    ];
    
    public function getSlugAttribute() 
    {
        return Str::slug($this->attributes['slug']);
    }
    
    public function getHumanFriendlyAttribute()
    {
        // problem arises from here
        return Carbon::parse($this->attributes['created_at'])->diffForHumans();
    }

    public function users()
    {
        return $this->belongsToMany(User::class);
    }
}

class User extends Authenticatable implements JWTSubject
{
    use HasApiTokens, HasFactory, Notifiable;

    protected $primaryKey='id';
    protected $table='users';
    protected $perPage=24;

    protected $appends = [];

    protected $fillable = [
        'username',
        'active',
        'email',
        'password',
        'slug',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
        'active'=>'boolean',
    ];

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }

    public function links()
    {
        return $this->belongsToMany(Link::class);
    }
}

The pivot table also has timestamp columns (the migration schema):

Schema::create('link_user', function (Blueprint $table) {
            $table->bigInteger('link_id')->unsigned()->index();
            $table->bigInteger('user_id')->unsigned()->index();
            $table->primary(['link_id', 'user_id']);
            $table->timestamp('created_at')->useCurrent();
            $table->timestamp('updated_at')->useCurrent();

            $table->foreign('link_id')->references('id')->on('links')->onDelete('cascade');
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        });

As you can see there is nothing out of the ordinary although I do suspect it's because the pivot table also have the timestamp columns. Has anyone else ran into this problem and shed some light on this problem?

Aside from this, the JSON is received very well. Thanks in advance.

1

There are 1 best solutions below

3
Jitendra Kumar On

The issue you're encountering is related to the created_at column not being available on the links table, but it's being accessed in the getHumanFriendlyAttribute accessor of your Link model. The problem doesn't seem to be directly related to the pivot table's timestamps.

To resolve this issue, you have a few options:

  1. Ensure created_at Column Exists: The most straightforward solution is to make sure that the created_at column exists in your links table. If it's not present and you want to use it in your accessor, you should create it in the table schema.
Schema::create('links', function (Blueprint $table) {
    #This line adds created_at and updated_at columns
    $table->timestamps(); 
});

If you don't intend to use these columns, you can omit the $table->timestamps() line, and Laravel won't expect them.

  1. Customize Accessor: If you don't want to add the created_at column to your links table, you can modify the getHumanFriendlyAttribute accessor to handle cases where the column might not exist. You can check if the column exists in the $attributes array before using it:
public function getHumanFriendlyAttribute(){
    if (array_key_exists('created_at', $this->attributes)) {
        return Carbon::parse($this->attributes['created_at'])->diffForHumans();
    } else {
        return 'N/A';// or any default value
    }
}

This way, if the created_at column is missing, it will return a default value or handle it as you see fit.

  1. Remove created_at Accessor: If you don't actually need the created_at attribute in your JSON response, you can remove the getHumanFriendlyAttribute accessor altogether if it's not essential for your application.

Choose the option that best fits your requirements, whether it's adding the created_at column, customizing the accessor, or removing it based on your specific needs.