Framework: Eloquent ORM goes OOM on delete() for a model without primary key

Created on 3 Mar 2014  路  10Comments  路  Source: laravel/framework

For a model with:

protected $primaryKey = null;

when $instance->delete() is called, it fails with out of memory fatal error.

Most helpful comment

Still doesn't work.

class Article extends \Eloquent
{
    use \Illuminate\Database\Eloquent\SoftDeletingTrait;
    public $incrementing = false;
    protected $primaryKey = [
        'article_id',
        'publisher_id'
    ];
$item = Article::where('article_id', 1)->where('publisher_id', 1)->first();
// works fine
$item->delete();
// throws Exception

Result:

array_key_exists(): The first argument should be either a string or an integer
\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php:2297
public function getAttribute($key)
{
    $inAttributes = array_key_exists($key, $this->attributes);

All 10 comments

That's odd, but it's worth noting that delete() is not designed to work at all without a primary key.

What column is it supposed to delete with ?

If there is no primary key, it could delete specifying all columns. In any case, it should not fail with OOM but with a more meaningful error.
Still, using all columns to delete instance of a model without a primary key is the most anticipated action unless specifying an array for $primaryKey is possible.

If you were to implement that, (new MyModel())->delete() would delete the entire table, and you would often risk unintentional deletes. I think that would be a pretty bad idea.

That is true but it's not like you can accidentally put this into the code. Cases of models without primary key are rare anyway.

How about implementing $primaryKey being an array to support MySQL's combined primary keys?

@DSpeichert , you can use an array as a PK.

@anlutro Checking $this->exists first would mitigate the (new MyModel())->delete() problem.

(not that I think this should be implemented. Just saying).

Fixed.

Still doesn't work.

class Article extends \Eloquent
{
    use \Illuminate\Database\Eloquent\SoftDeletingTrait;
    public $incrementing = false;
    protected $primaryKey = [
        'article_id',
        'publisher_id'
    ];
$item = Article::where('article_id', 1)->where('publisher_id', 1)->first();
// works fine
$item->delete();
// throws Exception

Result:

array_key_exists(): The first argument should be either a string or an integer
\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php:2297
public function getAttribute($key)
{
    $inAttributes = array_key_exists($key, $this->attributes);

@YOzaz is right, I get the same exception.

I think Eloquent expects a string primary key to delete there, and can't handle cases where the primary key is a composite defined through an array (where it should add multiple constraints in the where).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RomainSauvaire picture RomainSauvaire  路  3Comments

JamborJan picture JamborJan  路  3Comments

felixsanz picture felixsanz  路  3Comments

jackmu95 picture jackmu95  路  3Comments

PhiloNL picture PhiloNL  路  3Comments