Justus250422's avatar

updateOrCreate function updating all fields with last item

I have a relationship table called "job_type_project" with fields "project_id", "hourly_rate", and "job_type_id". In the JobTypeController in the update function, I execute the updateOrCreate function which looks like this:

foreach ($request->projects_hourly_rate as $item) {
    $result = ProjectRateJobType::updateOrCreate(
        ['project_id' => $item['project']['id'], 'job_type_id' => $jobtype->id],
        ['hourly_rate' => $item['hourly_rate']]
    );
}

Generally it should work, but looking in the laravel console, it shows me that the query it executes looks like this:

update `job_type_project` set `hourly_rate` = '25'

Here is my Model for this table:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;

class ProjectRateJobType extends Model
{
    use HasFactory;


    protected $primaryKey = null;
    public $incrementing = false;
    protected $fillable = ['project_id', 'hourly_rate', 'job_type_id'];
    protected $table = 'job_type_project';
    public $timestamps = false;

    public function project(): BelongsTo
    {
        return $this->belongsTo(Project::class);
    }

    public function jobType(): BelongsTo
    {
        return $this->belongsTo(JobType::class);
    }
}

For example, if I have 10 items and each of them has a different hourly_rate, then all records in the table are updated with the last one, not each separately.

I don't know what it could be, please help.

0 likes
1 reply
tykus's avatar

Your first array should uniquely identify a record in the database; otherwise Eloquent will fetch the same first matching record everytime, and update only that record every iteration of the loop.

In addition, the lack of a primary key means that there is nothing to uniquely identify the record for updating. You probably will be better advised to re-introduce the primary key, and/or not rely on the updateOrCreate convenience

Please or to participate in this conversation.