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

arozhnov's avatar

arozhnov wrote a comment+100 XP

3mos ago

You described exactly my way of thinking about AI programming. In the middle of 2025 I was very sceptical about it, used only for autocomplete simple patterns. But in january 2026 I've tried agent with these new MCPs on the side project and were surprised by the progress they made. Now I can't allow agents to write code to my main project, because I see It won't respect our guidelines, but learning to use it extensively on side projects.

arozhnov's avatar

arozhnov wrote a reply+100 XP

5mos ago

For someone like me who have the same problem if future.

This is because of nonstandard behaviors of MySQL and MariaDB databases:

The first TIMESTAMP column in a table, if not explicitly declared with the NULL attribute or an explicit DEFAULT or ON UPDATE attribute, is automatically declared with the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP attributes.

From mysql docs.

To fix it you should explicitly set field as nullable and set default value in migration.

$table->timestamp('real')->nullable()->default(null);

Now your column won't be updated on other fields update.

arozhnov's avatar

arozhnov liked a comment+100 XP

5mos ago

You can solve it by splitting the validation in two steps:

$request->validate([
    'title' => 'required|unique:posts|max:255',
]);

$request->validate([
    'title' => 'required|unique:posts|max:255', // this is not necessary
    'body' => 'required',
]);
arozhnov's avatar

arozhnov wrote a reply+100 XP

5mos ago

It's always useful not only for topic starter but also for future generations that encounters same problems. Like me now.

arozhnov's avatar

arozhnov liked a comment+100 XP

5mos ago

@mkailbowdy foreignPivotKey refer or applies to the foreign key of the parent model in the pivot table, in this case the parent table Job class.

class Job extends Model
{
    ...
    public function tags()
    {
        return $this->belongsToMany(Tag::class, foreignPivotKey: 'job_listing_id');
    }
}

On the other hand, the relatedPivotKey refer or applies to the associated key of the relation. So to get the jobs associated to our tags in our Tag class, we are not interested in the foreign key of the parent model (the Tag) we are interested in the associated key of our Tag that points to Jobclass which is job_listing_id.

class Tag extends Model
{
    ...
    public function jobs()
    {
        return $this->belongsToMany(Job::class, relatedPivotKey: 'job_listing_id');
    }
}
arozhnov's avatar

arozhnov liked a comment+100 XP

5mos ago

@mkailbowdy Sorry a bit late but I was struggling on this as well. @justinefication has done a great job explaining the differences between the two key types but I was still confused about when to use them.

I realised that when specifying the key types as arguments in the belongsToMany function, you are just defining them. You aren't choosing to use one or the other. The belongsToMany function makes a series of assumptions out of the box that we don't see. I have written out the full-length version with all arguments and initial assumptions made by Laravel below for the job model:

class Job extends Model
{
		...
		public function tags()
		{
				return $this->belongsToMany(
						related: Tag::class, 
						table: "job_tag", 
						foreignPivotKey: "job_id", 
						relatedPivotKey: "tag_id", 
						parentKey: "id", 
						relatedKey: "id", 
						relation: null);
		}
}

You will note that above, the default assumption made by Laravel is that the name of the foreignPivotKey for the job_listing object referenced in the job_tag pivot table is: job_id. However, this is not true as in the job_tag pivot table the name used to reference the job_listing object is: job_listing_id. Because of this, we have to tell Laravel that the foreignPivotKey that it assumed is wrong and to use what we specify instead. So the code above becomes:

class Job extends Model
{
		...
		public function tags()
		{
				return $this->belongsToMany(
						related: Tag::class, 
						table: "job_tag", 
						foreignPivotKey: "job_listing_id", 
						relatedPivotKey: "tag_id", 
						parentKey: "id", 
						relatedKey: "id", 
						relation: null);
		}
}

which is equivalent to (when you remove all the correct assumptions made by Laravel):

class Job extends Model
{
		...
		public function tags()
		{
				return $this->belongsToMany(Tag::class, foreignPivotKey: "job_listing_id") 		
		}
}

The main thing to realise is that we only specify the foreignPivotKey here because that is the only assumption Laravel got wrong by default.

If we now go to the Tag model, Laravel gets the foreignPivotKey assumption correct because it is tag_id, however, it gets the relatedPivotKey assumption wrong as it assumes it to be job_id. The result is that we now have to specify the correct relatedPivotKey value:


class Tag extends Model
{
		...
		public function jobs()
		{
				return $this->belongsToMany(Job::class, relatedPivotKey: "job_listing_id") 		
		}
}

Hopefully this helps!

arozhnov's avatar

arozhnov liked a comment+100 XP

5mos ago

Can you explain the difference between foreignPivotKey and relatedPivotKey? I'm having trouble understanding when to use them.