Framework: Saving changed values for a row in a table without a primary key updates all rows.

Created on 13 Sep 2019  路  5Comments  路  Source: laravel/framework

  • Laravel Version: 5.8
  • PHP Version: 7.3
  • Database Driver & Version: mySQL whatever version comes with Homestead 9.0

Description:

I have a table that doesn't have an incremented ID or a primary key. When I attempt to update a value in one of the rows through Eloquent, every row is updated with that value.

Steps To Reproduce:

  1. Create a table with no incremented ID, no primary key, and no timestamps.
  2. Add a couple dummy columns.
  3. Add some dummy data to the table.
  4. Create your model:

Model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Field extends Model
{
    public $timestamps = false;
    public $incrementing = false;
    protected $primaryKey = null;

    public function scopeFldBookName($query, $fldbookname)
    {
        return $query->where('fldbookname', $fldbookname);
    }

    public function scopeVersion($query, $version)
    {
        return $query->where('version', $version);
    }
}
  1. Create a controller:
<?php

namespace App\Http\Controllers;

use App\Field;
use App\Http\Requests\FieldUpdateRequest;

class FieldController extends Controller
{
    public function update(FieldUpdateRequest $request)
    {
        $F = Field::version($request->input('version'))->fldBookName($request->input('fldbookname'))->first();

        $F->some_column = $request->input('some_column');

        try {
            $F->save();
        } catch (Exception $e) {
            throw new UIPrettyException($e->getMessage(), $e->getCode());
        }

        return response()->json(true);
    }
}

In the above code, only one field ($F) is being operated on, but if the value for 'some_column' has changed, the $F->save() will update all rows to the value specified by 'some_column'

Most helpful comment

You can't update Eloquent models without a primary key. Laravel has no way of identifying the record.

In general, Eloquent isn't meant to be used without a primary key.

All 5 comments

You can't update Eloquent models without a primary key. Laravel has no way of identifying the record.

In general, Eloquent isn't meant to be used without a primary key.

...but I can select, insert, and delete on the rows of this table using Eloquent without any problems. Update is where the bug occurs.

@zhegwood im not sure you will be able delete ! the thing is you need a primary key so Eloquent can know what element are you trying to update.

protected $primaryKey = dummy_column;

so when updating Eloquent will add that where statement where('dummy_column', dummy_column_value)->update ... else the update will fire without the where statement then it will have to update every element on your table.

This isn't supported, sorry.

I think it would be a good idea to throw an exception instead of silently overwriting any row in the table!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JamborJan picture JamborJan  路  3Comments

SachinAgarwal1337 picture SachinAgarwal1337  路  3Comments

fideloper picture fideloper  路  3Comments

felixsanz picture felixsanz  路  3Comments

lzp819739483 picture lzp819739483  路  3Comments