I forgot to mention, but I'm using Laravel 11 and PostgreSQL 16.
This is the error that appears: SQLSTATE[42703]: Undefined column: 7 ERROR: column "updated_at" of relation "contexto_acao" does not exist
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Hello, well, the title says it all. I’m seeding my database, which has the following relationship:
• contextos - table
• acoes - table
• contexto_acao - pivot table
The issue occurs when I try to seed:
$adicionar = Acao::create([
'nome' => 'Adicionar',
'slug' => 'adicionar',
'descricao' => '',
'criado_em' => now()
]);
$contexto = Contexto::create([
'nome' => 'Períodos',
'slug' => 'periodo',
'descricao' => '',
'criado_em' => now(),
]);
$contexto->acoes()->attach($adicionar->id, ['criado_em' => now()]);
Laravel is trying to fill the updated_at column in the pivot table, but I don’t have timestamps in my pivot. In fact, my pivot is a class that extends Pivot, and I’ve defined public $timestamps = false;. In my Acao and Contexto classes, in the belongsToMany relationship, I haven’t used ->withTimestamps()…
Let me know if you’d like any further adjustments!
Sorry for my english, it was Chatgpt :D
I forgot to mention, but I'm using Laravel 11 and PostgreSQL 16.
This is the error that appears: SQLSTATE[42703]: Undefined column: 7 ERROR: column "updated_at" of relation "contexto_acao" does not exist
@joao_uefrom please share your migration files for the models in question. You probably have $table->timestamps(); in your migration files.
I didn't find it
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('contextos', function (Blueprint $table) {
$table->id();
$table->string('nome');
$table->string('slug')->unique();
$table->string('descricao');
$table->timestamp('criado_em');
});
Schema::create('acoes', function (Blueprint $table) {
$table->id();
$table->string('nome');
$table->string('slug')->unique();
$table->string('descricao');
$table->timestamp('criado_em');
});
Schema::create('contexto_acao', function (Blueprint $table) {
$table->foreignId('contexto_id')->constrained('contextos');
$table->foreignId('acao_id')->constrained('acoes');
$table->string('descricao')->nullable();
$table->timestamp('criado_em');
$table->primary(['contexto_id', 'acao_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('contextos');
Schema::dropIfExists('acoes');
Schema::dropIfExists('contexto_acao');
}
};
@joao_uefrom check your database tables to see if the updated_at and/or deleted_at columns exist. Alternatively run php artisan migrate:fresh - just keep in mind that this will erase and recreate your database tables and all data will be lost.
@aruszala these columns do not exist in my table, as I want
Have you created a model class for the pivot table? If you have, make sure its $timestamps property is set to false.
@JussiMannisto I did this but without success
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\Pivot;
class ContextoAcao extends Pivot
{
public $timestamps = false;
public function acao(): BelongsTo
{
return $this->belongsTo(Acao::class, 'acao_id');
}
public function contexto(): BelongsTo
{
return $this->belongsTo(Contexto::class, 'contexto_id');
}
}
@joao_uefrom also make sure to add public $timestamps = false; to your Contexto and Acao models as I don't see $table->timestamps(); in the migration files.
@aruszala
yes, public $timestamps = false; is added to the Acao and Contexto models, but without success.
@joao_uefrom The attach() method has a 3rd parameter named $touches, which is true by default. Try passing false:
$contexto->acoes()->attach(
id: $adicionar->id,
attributes: ['criado_em' => now()],
touch: false
);
@aruszala for example
class Contexto extends Model
{
protected $table = 'contextos';
public $timestamps = false;
protected $fillable = [
'nome',
'contexto',
'descricao',
'criado_em'
];
public function acoes(): BelongsToMany
{
return $this
->belongsToMany(Acao::class, 'contexto_acao', 'contexto_id', 'acao_id')
->withPivot('descricao')
->using(ContextoAcao::class);
}
}
@JussiMannisto tried here, same problem... :(
@joao_uefrom Btw, don't set $timestamps to false on Contexto and Acao. It won't help and the timestamps will stop working on those models.
@JussiMannisto the updated_at and created_at columns do not exist in the database for these models. Take a look at the migration files that were posted.
@JussiMannisto yes, timestamps are set to false on purpose, I don't want them in these models!
@joao_uefrom you could try this in your models if you're not using the standard timestamp columns:
const CREATED_AT = 'criado_em';
const UPDATED_AT = null;
Then omit manually setting the ['criado_em' => now()] when creating models.
Take a look here:
@joao_uefrom also change the line for criado_em in your migration files to thtis:
$table->timestamp('criado_em')->useCurrent();
@aruszala In fact, I already did this, I have a customized base model with this, I just applied some changes when sending it here to make it "easier" to understand:
use Illuminate\Database\Eloquent\Model as EloquentModel;
abstract class Model extends EloquentModel
{
public const CREATED_AT = 'criado_em';
public const UPDATED_AT = 'modificado_em';
}
the code snippet ['criado_em' => now()] is in the seed exactly because public $timestamps = false; in the models, it is like this because I am not interested in the updated_atcolumn, I am only interested in created_at.
But whenever I try to insert into the pivot table, laravel insists on the updated_at column (which for me is called modificado_em), even though the pivot table is not marked to have timestamps with ->withTimestamps() in belongsToMany.
@aruszala
$table->timestamp('criado_em')->useCurrent();
that's interesting, I'll put it here, but I don't think it will have any effect on how laravel inserts
@joao_uefrom that's the problem. The model you're extending sets the UPDATED_AT field.
Add this to the models that DO NOT have the modificado_em in the database table:
public const UPDATED_AT = null;
@joao_uefrom if you're models are using:
public const CREATED_AT = 'criado_em';
public const UPDATED_AT = 'modificado_em';
then you shouldn't use public $timestamps = false; as you're actually using timestamps. You're just renaming the column names that should be used for them.
Just remember that if the migration DOES NOT have the modificado_em column, then add:
public const UPDATED_AT = null;
to the model also.
@aruszala in fact the pivot model (which would be where the problem was occurring) does not inherit my custom class, it inherits the laravel Pivot class itself
@joao_uefrom then add this to the model:
const CREATED_AT = 'criado_em';
const UPDATED_AT = null;
and REMOVE public $timestamps = false; as you're actually using the timestamp for CREATED_AT field.
I just tried this on a fresh Laravel 11 install and I had no issues.
Do you have any observers on any of the models? Have you walked through the exception stack trace carefully to see where the error comes from?
@aruszala @jussimannisto wait, that worked, moving "criado_em" => now() from seeding to $table->timestamp('created_on')->useCurrent(); migration. But was that really supposed to be a problem?
a correction* $table->timestamp('criado_em')->useCurrent();
translator's fault
@joao_uefrom if you're models are using:
public const CREATED_AT = 'criado_em';
public const UPDATED_AT = 'modificado_em';
then you shouldn't use public $timestamps = false; as you're actually using timestamps. You're just renaming the column names that should be used for them.
Just remember that if the migration DOES NOT have the modificado_em column, then add:
public const UPDATED_AT = null;
to the model also.
@aruszala Indeed, defining const UPDATED_AT = null; in Contexto and Acao also solves the problem, but for me, it doesn’t make sense, because $timestamps was already set to false. Shouldn’t Laravel ignore this?
@joao_uefrom it SHOULD NOT be set to false. You ARE using timestamps, you just renamed them.
@joao_uefrom these are the timestamps, you just renamed them:
public const CREATED_AT = 'criado_em';
public const UPDATED_AT = 'modificado_em';
@aruszala Yes, I am indeed using timestamps, but manually, only in these tables and without the updated_at column. I didn’t realize that Laravel was seeing the created_at column being added manually and then trying to add updated_at automatically. After all, the documentation says:
If you do not want these columns to be automatically managed by Eloquent, you should define a
$timestampsproperty on your model with a value offalse
that was exactly what I did.
I am very grateful for your help!
Please or to participate in this conversation.